我已经在字符之间建立了一个消息系统,如下所示。每个角色都通过以下方式进行对话:聊天,每个对话has_many:消息,其中一些属于参与者之一,其余参与者则属于其他参与者。Rails sql查询通过has_many查找属于两个不同用户的记录通过
character.rb
has_many :chats, foreign_key: "character_id",
dependent: :destroy
has_many :conversations, through: :chats, source: :conversation
has_many :messages
conversation.rb
has_many :messages
chat.rb
belongs_to :character
belongs_to :conversation
message.rb
belongs_to :character
belongs_to :conversation
两个字符 “阿尔夫”(character_id:1)之间的对话和 “巴兹”(character_id:2)将因此包括在聊天表具有相同的conversation_id两排(10,说):
Chats
character_id conversation_id
1 10
2 10
可能存在另一个会话(conversation_id:23),其中两个阿尔夫和巴兹都参与与第三用户(“校准”,character_id:7):
Chats
character_id conversation_id
1 23
2 23
7 23
重要的是,查询不选择该组会话。
我的问题是,你如何构建一个SQL查询来找到只有Alf和巴兹之间的对话?
我被卡住了,因为有三个步骤,所以三个SQL查询:首先你必须找到所有属于Alf的对话,然后从这些属性选择巴兹,最后从这些选择一个只属于Alf和Baz。你如何在一个“连锁”三个SQL查询?
我想沿着这些路线的东西:
alf_id = @alf.id
baz_id = @baz.id
find_by_sql(" SELECT *
FROM Chats
RIGHT JOIN Conversations
ON Chats.character_id = #{alf_id}
SELECT *
FROM Conversations
INNER JOIN Chats
ON Chats.conversation_id = Conversations.id
AND Chats.character_id = #{baz_id}
WHERE (conversation belongs to only 2 characters)
; ")
编辑 可能的解决方案? 任何人都可以说,如果这是正确与否?:
sender_id = @sender.id
recipient_id = @recipient.id
conversationID = find_by_sql("
SELECT Conversations.id FROM
(
(
(
Conversations INNER JOIN (Chats WHERE Chats.character_id=#{sender_id})
ON Chats.conversation_id=Conversations.id
)
INNER JOIN (Chats WHERE Chats.character_id = #{recipient_id})
ON Chats.conversation_id=Conversations.id
)
GROUP BY conversation_id
HAVING COUNT(Chats.conversation_id)=2
)
; ")