Ruby on Rails. Cómo uso el Registro Activo.construir método en a: pertenece a la relación?


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 a una relación has_many antes de que cualquiera de los registros se haya guardado.

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 guardará tanto el perro como la etiqueta con las claves foráneas 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 se establece en este caso debido al hecho de que en el momento en que se guarda, la nueva persona no tiene un id porque aún no se ha guardado.

Mis preguntas son:

  1. ¿Cómo funciona la compilación para que Rails sea lo suficientemente inteligente como para averiguar cómo guardar los registros en el orden correcto?

  2. ¿Cómo puedo hacer lo mismo en una relación belongs_to?

  3. ¿Dónde puedo encontrar documentación sobre este método?

Gracias

Author: Josh Crozier, 2009-04-24

2 answers

Donde está documentado:

De la documentación de la API bajo la asociación has_many en " Módulo ActiveRecord:: Associations:: ClassMethods "

Colección.build (atributos = {}, …) Devuelve uno o más objetos nuevos del tipo de colección que han sido instanciado con atributos y vinculado a este objeto a través de un clave externa, pero aún no han sido guardado. Nota: Esto solo funciona si el objeto asociado ya existe, no si es nil!

La respuesta a construir en la dirección opuesta es una sintaxis ligeramente alterada. En su 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 (al igual que el método "create" correspondiente que puede llamar a la colección)

¿Cómo es rails lo suficientemente inteligente? Es magia (o más exactamente, simplemente no lo sé, me encantaría averiguarlo!)

 143
Author: BushyMark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-01 23:09:04
@article = user.articles.build(:title => "MainTitle")
@article.save
 42
Author: nehpets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-15 16:01:25