更新时间:2023-02-05 15:21:16
以下将要求论坛具有 @tags
数组中的所有论坛标签.我假设 forum
不会多次使用相同的 forum_tag
.
The following will require the forums to have all the forum tags in the @tags
array. I am making the assumption that a forum
will not have the same forum_tag
more than once.
@forums = Forum.joins(:forum_tags).where(:forum_tags => {:name => @tags}).group("forums.id").having(['COUNT(*) = ?', @tags.length]).includes(:forum_tags).all
这将生成如下的 SQL 查询:
This will produce an SQL query like the following:
@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
对) 那么论坛必须包含所有标签.
This will group all the rows in the join table by forums that match the given tags. If the COUNT
function has the value of the total number of tags that you're looking for (and there are no duplicate forum
/forum_tag
pairs) then the forum must contain all the tags.
获取剩余标签(评论中提出的问题):
To get the leftover tags (question asked in the comments):
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
@forums_with_leftovers
中的每个 Forum
对象都有一个额外的属性 leftover_tags
,它包含每个论坛对象中的逗号分隔的标签列表不在原来的 @tags
变量中.
Each Forum
object in @forums_with_leftovers
will have an extra attribute leftover_tags
that contains a comma separated list of tags in each forum object that is not in the original @tags
variable.