Rails,按关联查找

Rails, find by association

我要为 rails 应用程序构建消息传递功能。

我考虑过 conversationsconversation_participantsconversation_messages

这意味着:

对话:

has_many :conversation_participants
has_many :conversation_messages, through: :conversation_participants

对话参与者:

belongs_to :conversation
belongs_to :user
has_many :conversation_messages

对话消息:

belongs_to :conversation_participant

到目前为止,还不错。

我只是遇到了一些情况:

希望有人能帮我解决这个问题!谢谢!

听起来您希望通过对话参与者在用户和对话之间建立关联。

How do I find the conversation for User 1 and User 2?

鉴于您的设置方式,这似乎不是一次独特的对话。用户 1 和 2 可能在一个对话中只有彼此,在另一个对话中有其他参与者。也就是说,如果您在 conversation_id 上加入 conversation_participants table 自身,您应该能够找到匹配项。还有其他方法可以解决这个问题,我很乐意提供更多信息。您决定处理此问题的方式也会影响您其他问题的答案。

更新:

查询看起来像这样:

SELECT cp1.conversation_id 
FROM conversation_participants as cp1 
JOIN conversation_participants as cp2 ON cp1.conversation_id = cp2.conversation_id 
WHERE cp1.participant_id = 1 and cp2.participant_id =2;

您可以排除 converstion_messages。这些是无关紧要的,需要包括用户。

#user 
has_many :conversations, through: converstion_participants

user_12_conv_ids = user_1.conversation_ids & user_2.conversation_ids
user_123_conv_ids = user_12_conv_ids & user_3.conversation_ids

user_123_conversations = Conversation.where(id: user_123_conv_ids) 

现在您可以 select 仅包含 1、2 和 3 的对话(如 user_ids)

conversations.select{|c| c.user_ids == user_ids}

您可能想进一步了解 merge and where 方法。

第一个示例如下所示:

Conversation.joins(:conversation_participants).merge(User.where(:id => user1_id)).merge(User.where(:id => user2_id))

每个 merge() 筛选结果。你不会想使用 merge(User.where(:id => [user1_id, user2_id])) 因为你会得到两个用户的所有对话,而不仅仅是常见的对话。

第二个示例与第一个示例类似。

在第三个示例中,您可以在查询末尾添加类似 .merge(User.where.not(:id => user6_id) 的内容,以不包括与用户 6 的对话。

更新

要动态链接多个 merge,您可以尝试类似的方法:

conversations = Conversation.joins(:conversation_participants)
user_ids.each{|uid| conversations.merge!(User.where(:id => uid))}