Объединение ассоциаций родителя, его детей и его детей с рельсами3 - PullRequest
0 голосов
/ 28 августа 2011

У меня есть модель 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', в которой CarrierWave настроен на модель Image для управления загруженными изображениями. Я почти уверен, что есть драгоценный камень, который, вероятно, упростит всю эту вещь, но я бы предпочел просто сделать то, что у меня есть, и заняться реализацией этого драгоценного камня позже, поскольку это, вероятно, потребует много сложных миграций таблиц и рефакторинга. .

1 Ответ

1 голос
/ 30 августа 2011

два запроса

Является ли 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...