Ruby on Rails ::包含与子模型的多态关联
使用多态关联时,是否可以在仅存在于某些类型中的子模型上运行包含?
例:
class Container belongs_to :contents, :polymorphic => true end class Food has_one :container belongs_to :expiration end class Things has_one :container end
在视图中我将要做的事情如下:
因此,当我加载c时,我想急切加载到期,因为我知道我将需要最后一个。 有没有办法这样做? 只定义一个常规:include得到我的错误,因为并非所有封闭类型都有子模型到期。
编辑答案
我最近发现当你按多态类型列过滤时,Rails支持急切加载多态关联。 所以没有必要声明假联想。
class Container belongs_to :content, :polymorphic => true end
现在通过container_type
查询Container
。
containers_with_food = Container.find_all_by_content_type("Food", :include => :content) containers_with_thing = Container.find_all_by_content_type("Thing", :include => :content)
老答案
这是一个黑客,因为没有直接的方法在一个查询中包含多态对象。
class Container belongs_to :contents, :polymorphic => true # add dummy associations for all the contents. # this association should not be used directly belongs_to :food belongs_to :thing end
现在通过container_type
查询Container
。
containers_with_food = Container.find_all_by_content_type("Food", :include => :food) containers_with_thing = Container.find_all_by_content_type("Thing", :include => :thing)
这导致对数据库的两次SQL调用(实际上是4个调用,因为rails为每个执行一个SQL :include
)
在一个SQL中无法执行此操作,因为您需要为不同的内容类型设置不同的列。
警告:不应直接使用Content
类上的虚拟关联,因为它会导致意外结果。
例如:假设contents
表中的第一个对象包含食物。
Content.first.food # will work Content.first.thing
第二个电话不起作用。 它可能会为您提供一个与Content
指向的Food
对象具有相同ID的Thing
对象。