查询 Activerecord HABTM 关系以包含数组的所有元素 [英] Query Activerecord HABTM relationship to include ALL elements of an array

查看:40
本文介绍了查询 Activerecord HABTM 关系以包含数组的所有元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 ForumForumTag HABTM 关系.我还有一个名为 @tags 的变量数组.该数组包含一些论坛标签的名称.我希望能够查询并找到具有数组所有值的所有论坛.我目前有:

I have a Forum and ForumTag HABTM relationship. I also have an array of variables named @tags . This array contains the names of some ForumTags. I want to be able to query and find all forums that have ALL the values of the array. I currently have:

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

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

然而,这将返回数组中具有至少一个值的所有论坛.

However, this returns all the forums that have AT LEAST ONE value in the array.

推荐答案

以下将要求论坛具有 @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.

这篇关于查询 Activerecord HABTM 关系以包含数组的所有元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆