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