本节下方是我的原始答案;我误读了这个问题,并认为 OP 只想要一个从指定用户收到消息的用户列表;我也没有注意到关于向指定用户发送消息的用户的部分。这是我的更新。如果有帮助,我将在下面留下原始答案。
在此版本的答案中,我将更改联接和 where 子句,以便查询检查sender_id
orrecipient_id
列:
User.joins("INNER JOIN messages ON (messages.sender_id = users.id OR messages.recipient_id = users.id)")
.where("messages.sender_id = ? OR messages.recipient_id = ?", current_user.id, current_user.id).uniq
对造成的误解表示歉意。
原始答案:
为了获得您联系过的所有用户,我认为最简单的方法是通过正常的活动记录查询方法来做到这一点。has_many
首先,像这样在User
模型中设置:
在你的User
模型中
has_many :messages_sent, class_name: "Message", foreign_key: :sender_id
has_many :messages_received, class_name: "Message", foreign_key: :recipient_id
然后,您可以像这样简单地使用关系进行查询:
User.joins(:messages_received).where(:messages=>{sender_id: current_user.id}).uniq
注意:替换current_user
为您用于存储目标用户的任何内容。
编辑
有人问为什么这比使用直接:messages_sent
关系更好。这种方法的优点是它全部在数据库级别完成,适当的索引可以完成它的工作。如果您有一个非常大的表,并且该用户已发送大量消息,则使用活动记录has_many
关系将需要您遍历大型集合,尝试查找唯一用户。
只是为了更清楚一点,这个查询应该呈现一个看起来像这样的 SQL 查询:
SELECT users.*
FROM users INNER JOIN messages ON messages.recipient_id = users.id
WHERE messages.sender_id = 1
用简单的英语,这基本上是对数据库说:“请给我所有收到用户 #1 发送的消息的用户”。