我正在尝试创建一个收件箱,用于用户之间的消息传递。
下表如下:
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
如何使用活动记录完成此操作?
发布于 2014-05-19 01:50:36
这应该是相当有效的:
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;
使用子查询sub
中的最新消息使用DISTINCT ON
计算所有用户。然后第二次连接到表users
来解析名称。
DISTINCT ON
的详细信息
Select first row in each GROUP BY group?
旁白:使用"id“和"name”作为列名并不是一个非常有用的命名约定。
发布于 2014-05-19 01:07:36
这个怎么样:
@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
模型中。
发布于 2014-05-19 03:19:49
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
https://stackoverflow.com/questions/23728320
复制相似问题