在保持:through
关系之前,是否仍然可以返回关联?
以下是类结构的简化版本:
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
通过
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
的预期/理想行为吗?
答案 0 :(得分: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
被持久化,否则bars
关系的SQL将无法获取它:
> 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>]>