найти ассоциацию has_and_belongs_to_many с несколькими идентификаторами включительно - PullRequest
0 голосов
/ 31 октября 2018

У меня есть производственная модель с отношением has_and_belongs_to_many к тегам.

У меня есть массив tag_ids = ['tag_one', 'tag_two'], и я хочу найти Productions, у которых есть эти два тега или более.

Пример: будет возвращена продукция с тегами ['tag_one', 'tag_two', 'tag_three'], но продукция с тегами ['tag_one', 'tag_three'] не будет.

Что я пробовал до сих пор:

Production.includes(:tags).where(tags: { id: ['tag_one','tag_two'] })

Этот запрос не является исчерпывающим, он возвращает продукцию, у которой есть tag_one ИЛИ tag_two

Production.includes(:tags).where(tags: { id: ['tag_one'] }).where(tags: { id: ['tag_two'] })

Этот возвращает пустой массив, я думаю, он ищет тег, который имеет оба идентификатора, что невозможно.

Если вы, ребята, имеете представление о том, как я могу решить эту проблему, это было бы замечательно

Спасибо

1 Ответ

0 голосов
/ 31 октября 2018

включает метод для включения связанных записей в окончательный набор результатов. Здесь вам нужно отфильтровать записи, используя связи, что можно сделать с помощью объединений .

Затем записи должны быть сгруппированы (по id). Поскольку таблица tags объединена, для каждой записи таблицы productions вы можете иметь полный список тегов записи. И в зависимости от вашей ситуации вы можете применять различные условия к этому списку тегов.

Для извлечения Production записей, которые имеют ТОЛЬКО заданные теги и ничего больше (т.е. записи с ['tag_one'] или ['tag_one', 'tag_two', 'tag_three'] будут игнорироваться):

Production.joins(:tags)
          .having("array_agg(tags.id ORDER BY tags.id ASC) = ARRAY[#{tag_ids.sort.map { |t| "'#{t}'" }.join(',')}]")
          .group('productions.id')

Для извлечения Production записей, которые имеют КАЖДЫЙ из заданных тегов (т.е. будет извлечена запись с тегами ['tag_one', 'tag_two', 'tag_three'])

Production.joins(:tags)
          .where(tags: { id: tag_ids })
          .having("count(*) = #{tag_ids.count}")
          .group('productions.id')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...