Ruby on rails 查询Activerecord HABTM关系以包括数组的所有元素

Ruby on rails 查询Activerecord HABTM关系以包括数组的所有元素,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,我有一个Forum和ForumTagHABTM的关系。我还有一个名为@tags的变量数组。此数组包含一些ForumTags的名称。我想能够查询和找到所有论坛,有所有的数组值。我目前有: @forums=Forum.joines(:Forum\u tags)。其中(:Forum\u tags=>{:name=>@tags})。包括(:Forum\u tags)。所有 但是,这将返回数组中至少有一个值的所有论坛。以下要求论坛在@tags数组中有所有论坛标记。我假设一个论坛不会多次具有相同的论坛标签

我有一个
Forum
ForumTag
HABTM的关系。我还有一个名为
@tags
的变量数组。此数组包含一些ForumTags的名称。我想能够查询和找到所有论坛,有所有的数组值。我目前有:

@forums=Forum.joines(:Forum\u tags)。其中(:Forum\u tags=>{:name=>@tags})。包括(:Forum\u tags)。所有


但是,这将返回数组中至少有一个值的所有论坛。

以下要求论坛在
@tags
数组中有所有论坛标记。我假设一个
论坛
不会多次具有相同的
论坛标签

@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\u标签对),则论坛必须包含所有标签

要获取剩余标签(评论中提出的问题):

@forums\u中的每个
论坛
对象(带有"剩菜"
将有一个额外的属性
剩菜"标记
,该属性包含每个论坛对象中不在原始
@tags
变量中的以逗号分隔的标记列表

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

唐·克鲁伊克山克提出的这个解决方案很聪明!它对我非常有效。但是,不需要最后一个.includes和.all。

就像一个符咒。后续:如果我想设置一个leftover_tags变量,将其设置为查询中包含的所有leftover标记。例如,如果有一个论坛标记为['foo'、'bar'、'blah'],并且标记数组只有['foo'、'bar']。。。。我希望剩余的_标签是['blah'],我已经用剩余标签的后续查询更新了答案。
@forums = Forum.joins(:forum_tags).where(:forum_tags => {:name => @tags}).group("forums.id").having(['COUNT(*) = ?', @tags.length]).includes(:forum_tags).all