2015-08-12 4 views
1

До того, как связь :through была сохранена, можно ли вернуть ассоциацию?has_many через ассоциацию перед сохранением

Вот упрощенная версия структуры класса:

class Foo < ActiveRecord::Base 
    has_many :quxes 
    has_many :bars, through: :quxes 
end 

class Bar < ActiveRecord::Base 
    # there is no has_many :quxes -- this class doesn't care 
end 

class Qux < ActiveRecord::Base 
    belongs_to :foo 
    belongs_to :bar 
end 

Итак, я хочу, чтобы совершать звонки, как foo.bars что эквивалентно foo.quxes.map(&:bars)

Я клонирование Foo с, но их не экономить , Qux s копируются из old_foo в new_foo по

new_foo.quxes << old_foo.quxes.map(&:dup) 

Пожалуйста, обратите внимание, что приведенные выше результаты в:

new_foo.quxes.first.foo == new_foo 

new_foo.quxes.first.foo_id == old_foo.id 

, который показывает, что связь существует, но еще не сохранены.

Мне кажется, теперь вы должны быть в состоянии сделать:

new_foo.bars # same as new_foo.quxes.map(&:bar) 

Но это на самом деле возвращает []

Возможно ли это объединение new_foo.bars на работу до new_foo и его новый quxes сохраняются? Это даже ожидаемое/желательное поведение для :through?

ответ

1

Отношение through все еще «работает» в том смысле, что вы можете нормально его манипулировать. Я думаю, что вы имеете в виду, что он не содержит bars, добавленного ни к одному из quxes. Это связано с тем, что отношение bars отделено от отношения quxes, даже если оно не является независимым. Другими словами, bars не просто quxes.map(&:bar), как вы говорите; она работает совершенно отдельный запрос, что-то вроде:

> puts foo.bars.to_sql 
SELECT "bars".* FROM "bars" INNER JOIN "quxes" ON "bars"."id" = "quxes"."bar_id" WHERE "quxes"."foo_id" = 1 
> puts new_foo.quxes.to_sql 
SELECT "quxes".* FROM "quxes" WHERE "quxes"."foo_id" = 1 

Это означает, что если ассоциированный bar не сохраняется, SQL в bars Relation будет не забрать его:

> persisted_foo.quxes.first.build_bar 
#<Bar id: nil> 
> persisted_foo.bars 
#<ActiveRecord::Associations::CollectionProxy []> 
> persisted_foo.quxes.first.save! 
> persisted_foo.reload 
> persisted_foo.bars 
#<ActiveRecord::Associations::CollectionProxy [#<Bar id: 1>]> 
+0

я нашел тот же вопрос/решение. При выполнении некоторых тестов я пытался использовать «Fabricate.build», который работает для отношений 1: N, но не для 1: N: N или 1: N-through. –

Смежные вопросы