Ruby on Rails: has_many durch Frustrationen
-
26-09-2019 - |
Frage
Ich habe ein frustrierendes Problem mit einem has_many durch: nämlich die Tatsache, dass die durch Modelle erst speichert erstellt werden. Leider muss ich eingestellten Daten bei diesen Modellen vor den Eltern zu speichern.
Hier ist die lose Setup:
class Wtf < ActiveRecord::Base
belongs_to :foo
belongs_to :bar
end
class Bar < ActiveRecord::Base
has_many :wtfs
has_many :foos, :through => :wtfs
end
class Foo < ActiveRecord::Base
has_many :wtfs
has_many :bars, :through => :wtfs
def after_initialize
Bar.all.each do |bar|
bars << bar
end
end
end
Es ist alles in Ordnung, außer, dass ich die „wtf“ 'für den Zugriff auf die vorherige speichern:
f = Foo.new => #
f.bars => [Liste der Bars]
leere Liste hier
f.wtfs => []
f.save! => True
ich jetzt Zeug
f.wtfs => [Liste der Sachen]
Ich ging sogar so weit, zu explizit erstellen die wtfs, dies zu tun:
def after_initialize
Bar.all.each do |bar|
wtfs << Wtf.new( :foo => self, :bar => bar, :data_i_need_to_set => 10)
end
end
Dies bewirkt, dass die f.wtfs gefüllt werden, aber nicht die Bars. Wenn ich speichern und abrufen, ich doppelt die erwarteten wtfs erhalten.
Wer irgendwelche Ideen?
Lösung
Ich glaube, Sie haben die richtige Idee mit dem Wtfs
direkt zu schaffen. Ich denke, es ist OK wird sich herausstellen, wenn Sie nur die Bars in der gleichen Zeit eingestellt:
def after_initialize
Bar.all.each do |bar|
wtfs << Wtf.new(:bar => bar, :data_i_need_to_set => 10) # Rails should auto-assign :foo => self
bars << bar
end
end
Schienen sollten die Datensätze korrekt gespeichert werden, da sie die gleiche Sammlung von Objekten sind. Die einzige ziehen könnte sein, dass, wenn Schienen nicht die Smarts haben zu prüfen, ob ein neuer Bar
Datensatz in den Bars Sammlung bereits ein Wtf
zugeordnet hat, könnte es sowieso schaffen. Probieren Sie es aus.
Andere Tipps
Könnten Sie nicht einen before_save
Handler auf Wtf schreiben, die die Daten eingestellt würden Sie setzen müssen? Es wäre sowohl Zugriff haben die Foo und Bar, wenn nötig.
Sie könnten das Verfahren eingestellt, dass bevölkert zu einer after_create Bar, wie folgt aus:
class Foo < ActiveRecord::Base
has_many :wtfs
has_many :bars, :through => :wtfs
after_create :associate_bars
def associate_bars
Bar.all.each do |bar|
bars << bar
end
end
end
Dies würde die wtfs macht bereits erstellt werden, wenn diese Methode aufgerufen wird.