class User < ActiveRecord::Base has_one :profile end class Profile < ActiveRecord::Base has_many :skills belongs_to :user end
我有一个模型skill.rb与以下关联
class Skill < ActiveRecord::Base belongs_to :profile end
我在技能表中有以下条目
id: name: profile_id: ==================================================== 1 accounting 1 2 martial arts 2 3 law 1 4 accounting 2 5 journalist 3 6 administration 1
等等,我怎么能查询所有的配置文件,比方说,“会计”&考虑到上述重新编码,“管理”技能将是id为1的概要.到目前为止,我试过以下
Profile.includes(:skills).where(skills: {name: ["accounting","administration"]} )
但不是找到id为1的个人资料 – 它让我[1,2],因为id为2的个人资料拥有“会计”技能,并且在数据库中执行“IN”操作
注意:我正在使用postgresql并且问题不仅仅是描述的配置文件的特定ID(我仅用作示例) – 原始问题是获取包含这两个提到的技能的所有配置文件.
我的activerecord join在postgres中触发以下查询
SELECT FROM "profiles" LEFT OUTER JOIN "skills" ON "skills"."profile_id" = "profiles"."id" WHERE "skills"."name" IN ('Accounting','Administration')
在Vijay Agrawal以下的答案是我已经在我的应用程序中已经有的东西,他和我的,查询使用IN通配符导致包含任何技能的配置文件ID,而我的问题是获得包含两种技能的配置文件ID.我确信必须有一种方法以原始问题中列出的相同查询方式修复此事,我很想知道这种方式.我希望我能得到更多帮助 – 谢谢
为清楚起见,我想在模型中查询具有多种技能的所有配置文件,并且与配置文件模型具有has_many关系 – 使用配置文件作为主要表而不是技能
使用Profile作为主表的原因是在分页中我不想从相关表中获取所有技能,比如20_000或更多行,然后根据profile.state列进行过滤.相反,任何人都希望只选择符合profile.state,profile.user.is_active和其他列的5条记录条件并匹配技能,而无需检索数千条不相关的记录,然后再次过滤它们.
解决方法
Skill.where(name: ["accounting","administration"]).group(:profile_id).having("count('id') = 2").pluck(:profile_id)
如果您需要配置文件详细信息,可以将此查询放在Profile for id的where子句中.
注意查询中的数字2,它是在where子句中使用的数组的长度.在这种情况下[“会计”,“管理”].长度
更新::
基于更新的问题描述,您可以使用select和add子查询来确保它在一个查询中发生,而不是使用pluck.
Profile.where(id: Skill.where(name: ["accounting","administration"]).group(:profile_id).having("count('id') = 2").select(:profile_id))
更多的是你可以控制排序,分页和其他where子句.不要在编辑中提到有任何问题.
更新2 ::
另一种使配置文件与两种技能相交的方法(可能效率低于上述解决方案):
profiles = Profile ["accounting","administration"].each do |name| profiles = profiles.where(id: Skill.where(name: name).select(:profile_id)) end