2012-04-10 4 views
11

Así que, estoy seguro de que soy un novato de Rails, y me estoy encontrando con lo que debe ser un problema bastante común, pero no puedo encontrar la respuesta aquí.Crear asociación antes de que se guarde el registro

que tienen un modelo Foo así:

class Foo < ActiveRecord::Base 
    has_many :bars 
end 

Bares belongs_to Foo, lo único que funciona. Ahora quiero crear un Foo y construir barra al mismo tiempo. De esta manera:

f = Foo.new(:baz => 'baz') 
bars.each do |b| 
    f.bars.build(:bizzy => b[:bizzy]) 
end 
f.save 

Sé que esto no va a funcionar porque el registro padre no existe, por lo que no existe la asociación, pero tiene que haber una manera de hacer esto. He conseguido temporalmente editando a esto:

f = Foo.new(:baz => 'baz') 
f.save 
f = Foo.find(:first, :conditions => {:baz => 'baz'}) 
bars.each do |b| 
    f.bars.create(:bizzy => b[:bizzy]) 
end 

Pero eso no es limpia, y está por todas partes desagradable.

¿Cuál es la forma correcta de hacerlo?

Respuesta

10

En la primera línea puede simplemente usar create en lugar de new. No necesita f.bars.create o f.bars.build, porque el objeto bar ya existe. Me gustaría hacer esto:

f = Foo.create(:baz => 'baz') 

bars.each do |b| 
    f.bars << b 
end 

Personalmente no iterar sobre la bars, pero sólo tiene que utilizar update_all:

f = Foo.create(:baz => 'baz') 
bars.update_all(:foo_id => f.id) 

Editar: es posible hacer esto sin guardar el registro en primer lugar. Esto funciona para mí:

f = Foo.new(:baz => 'baz') 

bars.each do |b| 
    f.bars << b 
end 

f.save 
+0

Huh, podría haber jurado que no fue posible. Tienes razón, después de que lo probé de nuevo, funcionó a las mil maravillas. ¡Gracias! – Eugene

+1

Me encontré con el mismo problema y me di cuenta de que para la última opción (f = Foo.new), tenía que eliminar ': foo_id, remove: presence => true' en el modelo de Bar (en mi propio código). – migu

Cuestiones relacionadas