【问题标题】:Rails, find by associationRails,按关联查找
【发布时间】:2023-03-09 18:44:01
【问题描述】:

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

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

【问题讨论】:

  • 您是否有理由希望将参与对话的用户设置在单独的表格中 - conversation_participants - 而不是仅使用您的 users 表格?
  • @jeffdill2 是的,假设该应用程序也有组。一个小组也应该有一个对话。如果有人被添加到该组,他也可以访问该对话,但不应看到旧消息。

标签: ruby-on-rails relationships


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您可能需要更多地研究mergewhere 方法。

    第一个示例如下所示:

    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、3 或 10 个用户找到共享对话。
    • 试一试:conversations = Conversation.joins(:conversation_participants) user_ids.each{|uid| conversations = conversations.merge(User.where(:id => uid))}
    • 明天去看看。非常感谢先生!
    【解决方案3】:

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

    如何找到用户 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;
    

    【讨论】:

    • 谢谢先生!这听起来与我的想法/想象的完全一样。可以给我一个关于该连接的简短代码示例吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多