In a rails app, i have a 3 models, Room, User and UsersRoom which is an association table between Room and User.
I want to query for a Room related to multiple users.
If i do:
Room.includes(:users_rooms).where(users_rooms: {Â user_id: user_ids }
I get all the room with at least one users_room containing one users_ids.
I want to get the room with users_rooms present for each user_ids.
Is there a clean way to do this without have to loop on the rooms after querying them ?
>Solution :
I would try the following:
Room
.select('rooms.*, COUNT(users_rooms.user_id)')
.joins(:users_rooms)
.where(users_rooms: { user_id: user_ids })
.group('rooms.id')
.having('COUNT(users_rooms.user_id) >= ?', user_ids.size)
Notes:
- The
COUNTin theselectis required because some database engine versions complain when usingCOUNTin thehavingwithout having it defined in theselectpart. You can try to remove that line. - The
joindoes aINNER JOINbetween both tables. - The
whereis want you already had. - The
groupgroups the found records into a single line and allows usingCOUNT. - The
havingonly returns thoseroomsthat had at leastuser_ids.sizeusers_roomsassociated.