我有一个模型Foo
。 Foo
有许多FooChild
类型的子项。 FooChild
有很多FooChildChild
。 Foo
,FooChild
和FooChildChild
都拥有并属于许多Bar
。我想在Foo
上创建一个方法或范围,它将返回与之关联的所有Bar
及其子关联。我目前在Foo
模型上有以下内容。
def foo_child_bars
b = []
self.foo_childs.includes(:bar).collect{|fc| b += fc.bar}
b.uniq
end
def foo_child_child_bars
b = []
self.foo_childs.includes(:foo_child_childs).collect{|fcc| b += fcc.bar}
b.uniq
end
def all_bars
(self.bars + self.foo_child_bars + self.foo_child_child_bars).uniq
end
所以现在我可以调用@foo.all_bars
,这样可行,因为.uniq
方法,我不会重复。
我认为这种操作效率很低,因为我正在执行三个单独的查询。理想情况下,我想用UNION
或者其他东西进行单个查询,以便数据库能够确保只返回唯一的记录并且我尽可能少地进行查询。
我也很好奇是否可以在嵌套关联上使用includes()
,以便foo_child_child_bars()
可以包含与所有:bars
关联的:foo_child_childs
这包括在内。
Bar
代表一个表'images'
,其Image
模型上设置了CarrierWave来管理上传的图片。我几乎肯定有一个宝石可能会简化整个事情,但我宁愿做出我的工作并稍后解决这个宝石实现,因为它可能涉及很多复杂的表迁移和重构
答案 0 :(得分:1)
两个查询
是Bar多态?
ids = Foo.includes(:foo_children => :foo_child_children).map{|foo| [foo.id, foo.foo_children.map(&:id), foo.foo_children.map(&:foo_child_child).flatten.compact.map(:&id)]}.flatten.compact
Bar.where(:obj_id => ids)