Me he actualizado a Rails 2.3.3 (desde 2.1.x) y estoy tratando de averiguar el método accepts_nested_attributes_for
. Puedo usar el método para actualizar objetos anidados existentes, pero no puedo usarlo para crear nuevos objetos anidados. Dado el ejemplo artificioso:Cómo crear objetos anidados utilizando accept_nested_attributes_for
class Product < ActiveRecord::Base
has_many :notes
accepts_nested_attributes_for :notes
end
class Note < ActiveRecord::Base
belongs_to :product
validates_presence_of :product_id, :body
end
Si trato de crear un nuevo Product
, con un anidado Note
, de la siguiente manera:
params = {:name => 'Test', :notes_attributes => {'0' => {'body' => 'Body'}}}
p = Product.new(params)
p.save!
Fracasa validaciones con el mensaje:
ActiveRecord::RecordInvalid: Validation failed: Notes product can't be blank
Entiendo por qué sucede esto, es por el validates_presence_of :product_id
en la clase Note
, y porque en el momento de guardar el nuevo registro, el Product
objeto no tiene un id
. Sin embargo, no quiero eliminar esta validación; Creo que sería incorrecto eliminarlo.
También pude resolver el problema creando manualmente el Product
primero, y luego agregando el Note
, pero eso vence la simplicidad de accepts_nested_attributes_for
.
¿Existe una forma estándar de Rails de crear objetos anidados en nuevos registros?
En Rails 3 Este problema se resuelve por el añadido: inverse_of opción de has_many, has_one y belongs_to. Ver p. http://www.daokaous.com/rails3.0.0_doc/classes/ActiveRecord/Associations/ClassMethods.html#M001988 en la sección "Asociaciones bidireccionales" –
He optado por deshabilitar la validación cuando: id == nil . Como eso solo debería ocurrir al escribir un nuevo registro anidado, espero que sea seguro. Es extraño que este problema haya llegado hasta 2.3.8. – aceofspades
inverse_of no parece funcionar cuando ambos padres del registro aún no existen, y por lo tanto no se puede probar ninguna identificación. Parece que este truco anidado es el único camino a seguir. :( – DGM