Estoy investigando cómo validates_presence_of realmente funciona. Supongamos que tengo dos modelosvalidates_presence_of with belongs_to associations, de la manera correcta
class Project < ActiveRecord::Base
[...]
has_many :roles
end
y
class Role < ActiveRecord::Base
validates_presence_of :name, :project
belongs_to :project
end
lo quiero por lo que el papel siempre pertenece a un proyecto existente, pero me acabo de enterar de this example que esto podría conducir a papeles no válidos (huérfanos) guardados en el db. Entonces, la manera correcta de hacerlo es insertar el validates_presence_of :project_id
en mi modelo de Roles y parece funcionar, incluso si creo que semánticamente tiene más sentido para validar la presencia de un proyecto en lugar de una identificación de proyecto.
Además, estaba pensando que podría poner una identificación no válida (para un proyecto no existente) si solo valido la presencia de project_id, ya que de manera predeterminada AR no agrega verificaciones de integridad a las migraciones, e incluso si agrego de forma manual algunos DB no los admite (es decir, MySQL con MyISAM o sqlite). Este ejemplo demuestra que
# with validates_presence_of :name, :project, :project_id in the role class
Role.create!(:name => 'foo', :project_id => 1334, :project => Project.new)
AREL (0.4ms) INSERT INTO "roles" ("name", "project_id") VALUES ('foo', NULL)
+----+------+------------+
| id | name | project_id |
+----+------+------------+
| 7 | foo | |
+----+------+------------+
Por supuesto no voy a escribir código como este, pero quiero evitar este tipo de datos erróneos en DB.
Me pregunto cómo asegurar que un papel SIEMPRE tenga un proyecto (real y guardado) asociado.
Encontré la gema validates_existence, pero prefiero no agregar una gema a mi proyecto a menos que sea estrictamente necesario.
¿Alguna idea de esto?
actualización
validates_presence_of :project
y añadiendo :null => false
para la columna de project_id en la migración parece ser una solución más limpia.
Recomiendo usar la joya validates_existence para esto, ya que es exactamente lo que necesita. Además, es una dependencia bastante pequeña de tener. – Jits
Simplemente no rápido: asegúrese de usar su base de datos para validar también. Hacer la vida mucho más segura. – CharlesJHardy
@Jits, creo que haré eso. @Chuck Haré eso también, pero de esa manera no tendré errores de validación, por lo que todavía necesito validación a nivel de ruby. – Fabio