ruby-on-rails - new - rails 5 many to many
Ruby on Rails. ¿Cómo uso el método.build de Active Record en a: pertenece a la relación? (2)
No he podido encontrar ninguna documentación sobre el método .build en Rails (actualmente estoy usando 2.0.2).
A través de la experimentación, parece que puede usar el método de compilación para agregar un registro en una relación has_many
antes de que se haya guardado cualquiera de los registros.
Por ejemplo:
class Dog < ActiveRecord::Base
has_many :tags
belongs_to :person
end
class Person < ActiveRecord::Base
has_many :dogs
end
# rails c
d = Dog.new
d.tags.build(:number => "123456")
d.save # => true
Esto salvará tanto al perro como a la etiqueta con las claves externas correctamente. Esto no parece funcionar en una relación belongs_to
.
d = Dog.new
d.person.build # => nil object on nil.build
También he intentado
d = Dog.new
d.person = Person.new
d.save # => true
La clave foránea en Dog
no está configurada en este caso debido a que en el momento en que se guardó, la nueva persona no tiene una identificación porque aún no se ha guardado.
Mis preguntas son:
¿Cómo funciona la construcción para que Rails sea lo suficientemente inteligente como para descubrir cómo guardar los registros en el orden correcto?
¿Cómo puedo hacer lo mismo en una relación
belongs_to
?¿Dónde puedo encontrar documentación sobre este método?
Gracias
Donde está documentado:
De la documentación de API bajo la asociación has_many en " Módulo ActiveRecord :: Associations :: ClassMethods "
collection.build (attributes = {}, ...) Devuelve uno o más objetos nuevos del tipo de colección que se han instanciado con atributos y se han vinculado a este objeto a través de una clave externa, pero aún no se han guardado. Nota: Esto solo funciona si ya existe un objeto asociado, ¡no si es nulo!
La respuesta para construir en la dirección opuesta es una sintaxis ligeramente alterada. En tu ejemplo con los perros,
Class Dog
has_many :tags
belongs_to :person
end
Class Person
has_many :dogs
end
d = Dog.new
d.build_person(:attributes => "go", :here => "like normal")
o incluso
t = Tag.new
t.build_dog(:name => "Rover", :breed => "Maltese")
También puede usar create_dog para guardarlo instantáneamente (muy parecido al método de "crear" correspondiente que puede invocar en la colección)
¿Cómo es que los rieles son lo suficientemente inteligentes? Es mágico (o más exactamente, simplemente no lo sé, ¡me encantaría saberlo!)
@article = user.articles.build(:title => "MainTitle")
@article.save