I am trying to query for a record with a specific set of associations. It's a sort of existence query through a join. I want to query for a user who has exactly skill_1, skill_2, skill_3 with level_a, level_b, level_c
class User < ApplicationRecord
has_many :skills
end
class Skill < ApplicationRecord
belongs_to :user
end
# example of current attempt and intended use
def user_exists?(skills, levels)
User.joins(:skills).where(skill_name: skills, skill_level: levels)
end
This will give Users where they have a skill IN skills with a level IN levels, which returns all kinds of combinations of skill and level sets, but I only want the Users with exactly those skills at exactly those levels.
How can I write that query?
So say I have
skills = ['a','b','c']andlevels = [1,2,3].Based on your question there are 2 possible iterpretations:
[["a", 1], ["a", 2], ["a", 3], ["b", 1], ["b", 2], ["b", 3], ["c", 1], ["c", 2], ["c", 3]]; or[["a", 1], ["b", 2], ["c", 3]]Option 1: we can solve this as:
This will result in the following SQL:
Option 2: we can solve this as: (this assumes
skills.size == levels.size)This will result in the following SQL:
Option 2 could also be written as:
which would produce a WHERE clause for skills of
There are other ways these queries can be accomplished using things like intersection queries but the construction is a bit less straight forward.