2014-05-19 43 views
0

我正在嘗試爲用戶之間的消息傳遞創建收件箱。
這裏有如下表:顯示來自消息表的最新消息,按用戶分組

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執行此操作?

回答

0

這應該是相當有效:

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
Select first row in each GROUP BY group?

旁白:使用「ID」和「名稱」列名是不是一個非常有用的命名約定。

+0

太棒了!謝謝歐文。如何在Active Records中執行此操作,請 – user3649729

+0

@ user3649729:您可以使用原始SQL,如在此相關答案中通過mu解釋的那樣:http://stackoverflow.com/questions/10633412/table-join-sql-to-rails-active -record查詢/ 10639918#10639918 –

0

如何:

@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模型。

+0

@ user3649729 ahhh ..這有點棘手......讓我想一下它的一點點! – Mohamad

+0

@ user3649729由於您使用的是同一張表,因此您可能可以執行某種類型的聯合查詢或兩個查詢,然後合併並排序結果... – Mohamad

+0

感謝Mohamad。我現在正在收到錯誤。 – user3649729

0
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