I have a User model and a Conversation model. User has many conversations and Conversation has many users, so I use has_and_belongs_to_many relationship through join table :conversations_users. I use the method to return the conversation between specific users (by user id):
def find_conversation_between_users(ids)
conversation = nil
conversations = Conversation.all
if conversations.present?
conversations.each do |conv|
next unless conv.user_ids == ids.sort
conversation = conv
end
end
end
class Conversation < ApplicationRecord
has_and_belongs_to_many :users
end
class User < ApplicationRecord
has_and_belongs_to_many :conversations
end
It works but it won't be efficient if we would have thousands of conversations and it will take too much time to iterate over each of them. So I try to create the scope that returns the specific conversation by related user_ids [1 , 2, 3].
scope :by_user_id, ->(user_ids) { joins(:conversations_users).where([ conversations_users: { user_id: user_ids } ]) }
But it does not works.
Try this way:
class Conversation < ApplicationRecord
has_and_belongs_to_many :users
scope :by_user_id, ->(ids) { joins(:users).where(users: { id: ids }).group(:id).having("count(*) >= ?", ids.size) }
end