Ruby on Rails ::包含与子模型的多态关联 [英] Ruby on Rails: :include on a polymorphic association with submodels
问题描述
使用多态关联时,是否可以在仅存在于某些类型中的子模型上运行包含?
When working with a polymorphic association, is it possible to run an include on submodels that are only present in some types?
示例:
class Container
belongs_to :contents, :polymorphic => true
end
class Food
has_one :container
belongs_to :expiration
end
class Things
has_one :container
end
在视图中我想要做的事情如下:
In the view I'm going to want to do something like:
<% c = Containers.all %>
<% if c.class == Food %>
<%= food.expiration %>
<% end %>
因此,我想在加载c时急切加载到期,因为我知道我将需要最后一个。有没有办法这样做?只是定义一个常规:include得到我的错误,因为并非所有封闭类型都有子模型到期。
Therefore, I'd like to eager load the expirations when I load up c, because I know I will need every last one of them. Is there any way to do so? Just defining a regular :include gets me errors because not all enclosed types have a submodel expiration.
推荐答案
编辑的答案
我最近发现当你按多态类型列过滤时,Rails支持急切加载多态关联。所以没有必要声明假联想。
I recently found out that Rails supports eager loading of polymorphic associations when you filter by the polymorphic type column. So there is no need to declare fake associations.
class Container
belongs_to :content, :polymorphic => true
end
现在查询 Container
by container_type
。
containers_with_food = Container.find_all_by_content_type("Food",
:include => :content)
containers_with_thing = Container.find_all_by_content_type("Thing",
:include => :content)
旧答案
这是一个hack因为没有直接的方法在一个查询中包含多态对象。
This is a hack as there is no direct way to include the polymorphic objects in one query.
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
查询容器
。
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
)
That results in two SQL calls to the database ( actually it is 4 calls as rails executes one SQL for every :include
)
在一个SQL中无法执行此操作,因为您需要针对不同内容类型设置不同的列。
There is no way to do this in one SQL as you need different column set for different content types.
警告:虚拟关联内容
类不应该直接使用,因为它会导致意外结果。
Caveat: The dummy associations on Content
class should not be used directly as it will result in unexpected results.
例如:让我们说第一个对象在th e 内容
表包含食物。
E.g: Lets say the first object in the contents
table contains food.
Content.first.food # will work
Content.first.thing
第二次通话无效。它可能会给你一个 Thing
对象,其id与内容指向的
。 Food
对象相同
The second call will not work. It might give you a Thing
object with the same id as the Food
object pointed by Content
.
这篇关于Ruby on Rails ::包含与子模型的多态关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!