如何搜索查询多个关联的用户?

时间:2016-03-14 07:04:04

标签: ruby-on-rails ruby postgresql ruby-on-rails-4 search

好。我们假设有一个包含多个连接表的用户模型。

用户

has_many :languages
has_many :skills
has_many :languages, through: :user_langauges
has_many :skills, through: :user_skills

如果我使用params(如

)命中终点
"user"=>
  { "email"=>"test@123.com",
   "languages"=>"["French", Spanish]",
   "skills"=>"["accounting", "leadership"]"
}

我如何搜索符合上述条件的用户?我主要担心的是如何搜索与"语言"和"技能"。是最好的采取所有用户并比较哪些用户是相同的?类似的东西:

french = French.users
leadership = Leadership.users
french & leadership # => "users that exist in both?"

显然,有更多的逻辑,但我觉得这个一般的想法是税收和效率低下。但是我确信rails已经想到了一种更优雅的方式,这就是为什么我需要你的轨道大师的指示:)

编辑:如果重要的话我有一个Psql DB。

1 个答案:

答案 0 :(得分:3)

不,你不想比较Ruby中的用户。如果你有很多用户/技能/语言,它将加载大量数据并且不会有效。

这就是数据库的用途。查看AR指南以了解如何查询数据库:http://guides.rubyonrails.org/active_record_querying.html 我还建议您阅读SQL,因为AR只能帮助您构建SQL查询。但权力来自你的数据库。

以下是一个粗略的示例:它如何运作:

User.joins(:languages, :skills).where(skills: {name: ['Ruby', 'Marketing']}, languages: {name: 'French'}).uniq

假设:用户,技能和语言的属性name会根据您的架构进行调整。

这将搜索具有以下内容的用户:(技能Ruby OR Marketing)并讲法语。

如果你不想拥有:ruby AND marketing AND french,那么查询会变得更复杂。

更新: 如上所述,AND组合更复杂。您将需要使用GROUP BY和HAVING,或者可以提供子查询来尝试计算技能。以下是原始SQL查询:

SELECT users.* FROM (
SELECT users.* FROM "users"
INNER JOIN "user_skills" ON "user_skills"."user_id" = "users"."id"
INNER JOIN "skills" ON "skills"."id" = "user_skills"."skill_id"
WHERE skills.name IN ('Ruby', 'Marketing')
GROUP BY users.id
HAVING COUNT(*) = 2
) users
INNER JOIN "user_languages" ON "user_languages"."user_id" = "users"."id"
INNER JOIN "languages" ON "languages"."id" = "user_languages"."language_id"
WHERE languages.name IN ('German', 'French', 'English')
GROUP BY users.id, users.name, users.created_at, users.updated_at
HAVING COUNT(users.*) = 3

数字(2,3)必须是您需要的比赛数量(2种技能,3种语言)。