从用户分组显示消息表中的最新消息

我正在尝试为用户之间的消息传递创建一个收件箱。
以下是表格:

Messsages Id | Message_from | message_to | message 1 | 2 | 1 | Hi 2 | 2 | 1 | How are you 3 | 1 | 3 | Hola 4 | 4 | 1 | Whats up 5 | 1 | 4 | Just Chilling 6 | 5 | 1 | Bonjour Users Id | Name 1 | Paul 2 | John 3 | Tim 4 | Rob 5 | Sarah 6 | Jeff 

我想显示一个收件箱,其中显示该人员已与之通信的用户列表以及来自任一用户的last_message

保罗的收件箱:

 Name | user_id | last_message Sarah| 5 | bonjour Rob | 4 | Just Chilling Tim | 3 | Hola John | 2 | How are you 

如何使用Active Records执行此操作?

这应该是相当有效的:

 SELECT u.name, sub.* FROM ( SELECT DISTINCT ON (1) m.message_from AS user_id , m.message AS last_message FROM users u JOIN messages m ON m.message_to = u.id WHERE u.name = 'Paul' -- must be unique ORDER BY 1, m.id DESC ) sub JOIN users u ON sub.user_id = u.id; 

使用DISTINCT ON在子查询sub使用最新消息计算所有用户。 然后第二次加入表users来解析名称。

DISTINCT ON详细信息:
选择每个GROUP BY组中的第一行?

旁白:使用“id”和“name”作为列名称不是一个非常有用的命名约定。

这个怎么样:

 @received_messages = current_user.messages_to.order(created_at: :desc).uniq 

如果您还要包含来自用户的消息,则可能必须执行联合查询或两个查询,然后合并并加入它们。 我只想猜测一些伪代码,但是这应该会让你在路上。

 received_messages = current_user.messages_to sent_messages = current_user.messages_from (received_messages + sent_messages).sort_by { |message| message[:created_at] }.reverse 

这种类型的逻辑属于模型,而不是控制器,因此您可以将其添加到message模型中。

 scope :ids_of_latest_per_user, -> { pluck('MAX(id)').group(:user_id) } scope :latest_per_user, -> { where(:id => Message.latest_by_user) } Message.latest_per_user