[英]Active Record Rails 4 Unique Query on Collection
My users have many 'received_messages' and 'sent_messages' (from a join table that just contains a receiver_id, sender_id, and the content). 我的用户有很多“ received_messages”和“ sent_messages”(来自仅包含了receive_id,sender_id和内容的联接表)。 My associations are all set up correctly and when I call user.received_messages and user.sent_messages I am returned the correct collections. 我的关联都正确设置,当我调用user.received_messages和user.sent_messages时,我将获得正确的集合。 What I am now trying to do is filter the returned message collections so they will only return the first(newest) message from each unique sender(if it is received_messages) or receiver(if it is sent_messages). 我现在想做的是过滤返回的消息集合,这样它们将仅从每个唯一发件人(如果是receive_messages)或接收者(如果是send_messages)返回第一(最新)消息。
I have tried : 我努力了 :
@sent_messages = @user.sent_messages.uniq(&:receiver_id) @sent_messages = @user.sent_messages.select(:receiver_id).distinct
Etc but this keeps returning to me an array of numbers rather than actual collections. @sent_messages = @user.sent_messages.uniq(&:receiver_id) @sent_messages = @user.sent_messages.select(:receiver_id).distinct
等等,但这总是向我返回一组数字,而不是实际的数字。
Not sure if this is relevant but in my User model the associations are set up as : 不确定是否相关,但是在我的用户模型中,关联设置为:
has_many :received_messages, class_name: 'Message', foreign_key: 'receiver_id', table_name: 'messages' has_many :sent_messages, class_name: 'Message', foreign_key: 'sender_id', table_name: 'messages'
and in the Message model: 在消息模型中:
belongs_to :sender, foreign_key: 'sender_id', class_name: "User" belongs_to :receiver, foreign_key: 'receiver_id', class_name: "User"
Try this: 尝试这个:
message_per_uniq_receiver = @user.sent_messages.select('DISTINCT ON (receiver_id) *')
.order('receiver_id, messages.created_at DESC')
message_per_uniq_sender = @user.received_messages.select('DISTINCT ON (sender_id) *')
.order('sender_id, messages.created_at DESC')
This DISTINCT ON
is kinda complex ( documentation here ): 此DISTINCT ON
有点复杂( 此处的文档 ):
Long story short, the DISTINCT ON(sender_id)
will create groups for each distinct sender_id
found in the messages table, and will select the first of each group, the first of the group is determined by the ORDER BY
clause. 长话短说, DISTINCT ON(sender_id)
将为在消息表中找到的每个不同的sender_id
创建组,并将选择每个组的第一个,该组的第一个由ORDER BY
子句确定。
The "select" method is like the SELECT command in SQL. “选择”方法类似于SQL中的SELECT命令。 It selects a database column and returns data. 它选择一个数据库列并返回数据。
Thus, sent_messages.select(:receiver_id)
returns the receiver ID, which is an integer. 因此, sent_messages.select(:receiver_id)
返回接收者ID,它是一个整数。
If you want sent_messages with a particular receiver ID, use the "where" method. 如果希望send_messages具有特定的接收者ID,请使用“ where”方法。
For example, sent_messages.where(receiver_id: some_receiver_id)
. 例如, sent_messages.where(receiver_id: some_receiver_id)
。
Start with your list of distinct receiver ID's. 从您的不同接收者ID列表开始。 Call it receiver_id_list. 称它为receive_id_list。 Then iterate through them. 然后遍历它们。 For each ID, find the newest message belonging to that receiver, and add it to an array. 对于每个ID,找到属于该接收者的最新消息,并将其添加到数组中。
most_recent_sent_messages = []
receiver_id_list.each do |id|
most_recent_sent_messages << @user.sent_messages.where(receiver_id: id).order(time_sent: :desc).first
end
The highest time_sent
(or whatever you named the timestamp) should be the newest message, which is why you should sort them in descending order. 最高的time_sent
(或称为timestamp的名称)应该是最新的消息,这就是为什么您应该按降序对它们进行排序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.