合并父母,其子女及其子女的儿童与Rails3的关联

时间:2011-08-28 19:43:59

标签: ruby ruby-on-rails-3 activerecord

我有一个模型FooFoo有许多FooChild类型的子项。 FooChild有很多FooChildChildFooFooChildFooChildChild都拥有并属于许多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来管理上传的图片。我几乎肯定有一个宝石可能会简化整个事情,但我宁愿做出我的工作并稍后解决这个宝石实现,因为它可能涉及很多复杂的表迁移和重构

1 个答案:

答案 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)