Запросите отношение Activerecord HABTM, чтобы включить ВСЕ элементы массива - PullRequest
2 голосов
/ 26 февраля 2012

У меня есть отношения Forum и ForumTag HABTM.У меня также есть массив переменных с именем @tags.Этот массив содержит имена некоторых тегов ForumTag.Я хочу иметь возможность запрашивать и находить все форумы, которые имеют ВСЕ значения массива.В настоящее время у меня есть:

@ forums = Forum.joines (: forum_tags) .where (: forum_tags => {: name => @tags}). Includes (: forum_tags) .all

Тем не менее, это возвращает все форумы, которые имеют по крайней мере одно значение в массиве.

1 Ответ

5 голосов
/ 26 февраля 2012

Для того, чтобы форумы имели все теги форумов в массиве @tags, в следующем порядке.Я делаю предположение, что forum не будет иметь один и тот же forum_tag более одного раза.

@forums = Forum.joins(:forum_tags).where(:forum_tags => {:name => @tags}).group("forums.id").having(['COUNT(*) = ?', @tags.length]).includes(:forum_tags).all

Это создаст запрос SQL, подобный следующему:

@tags = ['foo', 'bar']

SELECT forums.id, forum_tags.id FROM forums
  LEFT OUTER JOIN forum_tags_forums on forum_tags_forums.forum_id = forums.id
  LEFT OUTER JOIN forum_tags ON forum_tags.id = forum_tags_forums.forum_tag_id
  WHERE forum_tags.name IN ('foo', 'bar')
  GROUP BY forums.id
  HAVING COUNT(*) = 2;

Это сгруппирует все строки в объединяемой таблице по форумам, которые соответствуют заданным тегам.Если функция COUNT имеет значение общего количества тегов, которые вы ищете (и нет дублирующихся пар forum / forum_tag), тогда форум должен содержать все теги.

Чтобы получить оставшиеся теги (вопрос задан в комментариях):

forum_tags = ForumTag.where(:name => @tags)

@forums_with_leftovers = Forum.select("forums.*, GROUP_CONCAT(forum_tags.name) AS leftover_tags").joins(:forum_tags).where(['forums.id IN (?) AND NOT forum_tags.id IN (?)', @forums, forum_tags]).group("forums.id").all

Каждый Forum объект в @forums_with_leftovers будет иметь дополнительный атрибут leftover_tags, который содержит разделенный запятыми список тегов в каждомобъект форума, который не находится в исходной переменной @tags.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...