2011-08-28 26 views
0

我有一个模型FooFoo有许多FooChild类型的孩子。 FooChild有很多FooChildChildFoo,FooChildFooChildChild都有,属于很多Bar。我想在Foo上创建一个方法或范围,它将返回与它关联的所有Bar,它是子关联。我目前在Foo模型上有类似以下内容。合并一个家长,其子女和它的儿童的孩子的协会与Rails3

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()可以包括与所有:foo_child_childs的正被纳入相关的:bars的方式。

Bar在此减少表示'images'表其中CarrierWave设置在Image模型管理上传的图像。我几乎肯定有一个可能会简化整个事情的宝石,但我宁愿让自己的工作成功,并在稍后处理该宝石实现,因为它可能涉及大量复杂的表迁移和重构。

回答

1

两个查询

是酒吧多态吗?

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) 
+0

不幸的是'Bar'不是多态的。但我看到你在那里得到什么。 'Foo'是多态的。 “Foo”有大约4个从它继承的其他类。我在想,也许HABTM关于“Bar”的关系应该是多态的。你有任何建议进行迁移? – sholsinger

+0

看起来我应该这样做:http://guides.rubyonrails.org/association_basics.html#polymorphic-associations对我没有做到这一点,我感到羞耻。 – sholsinger