轨道,通过关联查找



我即将为一个 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

目前为止,一切都好。

我只是困在一些场景中:

  • 如何找到用户 1 和用户 2 的对话?
  • 如何为用户 1、用户 4 和用户 5 找到一个?
  • 如果有两个对话,一个用于用户 1,4,5,另一个用于 1,4,5,6,但我
  • 只是在寻找 1,4,5,怎么办?

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

您可以排除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) 

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

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

您可能希望更多地了解合并和 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))}

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

如何找到用户 1 和用户 2 的对话?

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

更新:

查询将如下所示:

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;

最新更新