Reputation: 1170
I am using a very standard has_and_belongs_to_many association, like the example in the Rails associations guide: http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
The problem is that I would like to query to find the Assembly with the exact match of parts. For instance, Assembly with 2 Parts associated to it, and the Parts having ids of 1, 2.
Here are my approaches that fail:
Assembly.joins(:parts).where(parts: {id: [1,2]})
Assembly.joins(:parts).
where('parts.id IN (?)', [1,2]).
group('assemblies.id').
having('COUNT(assemblies.id) >= ?', [1,2].length)
(This one was suggested by this SO answer: Rails scope - where in exact matches)
These approaches return Assembly objects which just have Parts with ids 1 and 2 included in their associated Parts. But again, what I want is only Assemblies with exactly those 2 Parts (ids 1 and 2).
Please help!
Upvotes: 2
Views: 483
Reputation: 2860
Update: Order of elements in PostgreSQL arrays are import. It's possible to use ORDER BY
inside ARRAY_AGG
function.
Assembly.joins(:parts).
group('assemblies.id').
having('ARRAY[?] = ARRAY_AGG(parts.id ORDER BY parts.id)', [1,2].sort)
First version:
If you are using PostgreSQL, you can do it with ARRAY_AGG group function:
Assembly.joins(:parts).
group('assemblies.id').
having('ARRAY[?] = ARRAY_AGG(parts.id)', [1,2])
Upvotes: 2