ruby-on-rails - formularios - validar campos rails
accept_nested_attributes_for validation de validaciĆ³n de asociaciĆ³n hija (6)
Al contrario de lo que sugiere Bigo, no siempre es aceptable guardar primero el objeto padre y luego los hijos. Por lo general, quiere asegurarse de que todos los objetos validen antes de comenzar a guardarlos. Eso le da al usuario la oportunidad de volver a editar el formulario de entrada y corregir cualquier error.
El problema que describes se solucionará en Rails 3.0. Hubiera publicado un enlace al ticket de Lighthouse, pero stackoverflow.com no lo permite porque soy un nuevo usuario (#fail). Pero por el momento, puede usar el complemento " parental_control ", que arreglará su "error".
Estoy usando accept_nested_attributes_for en uno de mis modelos de Rails, y quiero guardar los elementos secundarios después de crear el elemento primario.
El formulario funciona a la perfección, pero la validación está fallando. Por simplicidad, imagine lo siguiente:
class Project < ActiveRecord::Base
has_many :tasks
accepts_nested_attributes_for :tasks
end
class Task < ActiveRecord::Base
belongs_to :project
validates_presence_of :project_id
validates_associated :project
end
Y estoy corriendo:
Project.create!(
:name => ''Something'',
:task_attributes => [ { :name => ''123'' }, { :name => ''456'' } ]
)
Al guardar el modelo del proyecto, la validación está fallando en las tareas porque no tienen un project_id (ya que el proyecto no se ha guardado).
Parece que Rails sigue el siguiente patrón:
- Validar proyecto
- Validar tareas
- Guardar proyecto
- Guardar tareas
El patrón debería ser:
- Validar proyecto
- En Pase: Guardar Proyecto y continuar ...
- Validar tareas
- En Pase: Guardar Tareas
- En caso de error: Eliminar proyecto (¿retroceder quizás?)
Así que mi pregunta se reduce a: ¿Cómo puedo hacer que Rails ejecute el método project_id = (o project =) y la validación en los hijos (tareas) DESPUÉS de que el padre (proyecto) se haya guardado, pero NO guarde el modelo padre (proyecto) si algún niño (tarea) no es válido?
¿Algunas ideas?
Lamentablemente, ninguna de las sugerencias anteriores funciona para mí con Rails 2.3.5.
En mi caso, el proyecto en una tarea es siempre nulo si ambos se crean usando atributos anidados. Solo si elimino la validates_presence_of, la creación se realiza correctamente. La prueba de la unidad y el registro muestran que todo se creó correctamente.
Por lo tanto, ahora tendería a agregar restricciones al DB en lugar de Rails, ya que eso parece ser más confiable en primer lugar.
Simplemente podría crear el proyecto y solo agregar los proyectos si pasa la validación:
tasks = params.delete(:task_attributes)
if Project.create(params)
Project.update_attributes(:task_attributes => tasks)
end
Ciao
Solo valide la relación, no la ID:
class Task < ActiveRecord::Base
belongs_to :project
validates_presence_of :project
end
Tan pronto como se rellene la asociación, ActiveRecord considerará que la validación ha tenido éxito, independientemente de que el modelo se haya guardado o no. Es posible que también desee investigar el autoguardado para asegurarse de que el proyecto de la tarea siempre se guarde:
class Task < ActiveRecord::Base
belongs_to :project, :autosave => true
validates_presence_of :project
end
Use :inverse_of
y validates_presence_of :parent
. Esto debería arreglar su problema de validación.
class Dungeon < ActiveRecord::Base
has_many :traps, :inverse_of => :dungeon
end
class Trap < ActiveRecord::Base
belongs_to :dungeon, :inverse_of => :traps
validates_presence_of :dungeon
end
http://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_presence_of
Utilice esta respuesta para Rails 2; de lo contrario, consulte a continuación la respuesta de :inverse_of
Puede evitar esto al no verificar el project_id si el proyecto asociado es válido.
class Task < ActiveRecord::Base
belongs_to :project
validates_presence_of :project_id, :unless => lambda {|task| task.project.try(:valid?)}
validates_associated :project
end