2012-04-10 13 views
11

Quindi, sono un novizio di Rails, e mi sto imbattendo in quello che deve essere un problema abbastanza comune, ma non riesco a trovare la risposta qui.Crea associazione prima che il record venga salvato

Ho un modello Foo come questo:

class Foo < ActiveRecord::Base 
    has_many :bars 
end 

Bar belongs_to Foo, tutto ciò che funziona. Ora voglio creare un Foo e costruire Bar allo stesso tempo. Come questo:

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

So che questo non funzionerà perché il record principale non esiste, quindi l'associazione non esiste, ma ci deve essere un modo per farlo. Mi sono temporaneamente aggirato modificando questo:

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 

Ma questo non è pulito, ed è tutt'intorno sgradevole.

Qual è il modo giusto per farlo?

risposta

10

Nella prima riga è possibile utilizzare solo create anziché new. Non è necessario f.bars.create o f.bars.build, poiché l'oggetto bar esiste già. Vorrei farlo:

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

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

Personalmente non sarebbe iterare il bars, ma basta usare update_all:

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

Edit: è possibile farlo senza salvare il record prima. Questo funziona per me:

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

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

f.save 
+0

Huh, avrei giurato che non era possibile. Hai ragione però, dopo averlo testato di nuovo, ha funzionato come un fascino. Grazie! – Eugene

+1

Ho sperimentato lo stesso problema e mi sono reso conto che per l'ultima opzione (f = Foo.new), dovevo rimuovere ': foo_id, remove: presence => true' sul modello Bar (nel mio codice). – migu

Problemi correlati