2017-10-14 123 views
0

我創建了一個私人消息系統,但我在收件箱中遇到問題。 我想創建一個定期收件箱,您可以在其中查看所有對話。 我試圖做一些事情,但是我得到了用戶得到的所有消息的結果,但我只想顯示來自每個對話的最後一條消息。Rails僅顯示收件箱中用戶的最後一條私人消息

SQL: 我得到了帶有id,user_id(int),to_id(int),content(text),read(boolean)的消息表。

消息控制器:

def inbox 
@messages = Message.where("to_id = ? OR user_id = ? AND to_id != 0", current_user, current_user).order(created_at: :desc) 
end 

查看:

<% @messages.each do |message| %> 
    <% to_user_id = User.find(message.to_id) %> 
    <% to_user_name = to_user_id.username %> 
    <b><p><%= to_user_name %></p></b> 
    <p> 
    <% if message.read == false %> 
     <b><%= link_to message.content, pm_path(to_user_id) %></b> 
    <% else %> 
     <%= link_to message.content, pm_path(to_user_id) %> 
    <% end %> 
    </p> 
    <% end %> 

希望我自己清楚,謝謝你提前。

回答

0

試試這個

@messages = Message.find_by("(to_id = ? OR user_id = ?) AND to_id != 0", current_user, current_user).order(created_at: :desc) 
+0

Dosent work .... –

0

如果您設置的關聯正確實在是小巫見大巫:

class User < ApplicationRecord 
    has_many :recieved_messages, class_name: 'Message', foreign_key: 'recipent_id' 
    has_many :sent_messages, class_name: 'Message', foreign_key: 'sender_id' 

    def all_messages 
    Message.where('recipient_id = :id OR sender_id = :id', id: id) 
    end 
end 

class Message < ApplicationRecord 
    belongs_to :recipient, class_name: 'User', inverse_of: :recieved_messages 
    belongs_to :sender, class_name: 'User', inverse_of: :sent_messages 

    def self.between(a,b) 
    .where('(recipient_id = :id OR sender_id = :id)', id: a) 
    .where('(recipient_id = :id OR sender_id = :id)', id: b) 
    end 
end 

# all messages recieved by the current user: 
current_user.recieved_messages.order(created_at: :desc) 

# all messages recieved by the current user: 
current_user.sent_messages.order(created_at: :desc) 

# all messages sent or recieved by the current user: 
current_user.all_messages.order(created_at: :desc) 

# all messages between two users 
Message.between(current_user, some_other_user) 

,這是讓用戶之間的任何消息的關鍵是:

WHERE (recipient_id = a OR sender_id = a) AND (recipient_id = b OR sender_id = b) 

但你應該考慮創建一個會話模型來加入它們。

調用.last將按降序排列後得到最早的記錄。如果你想要最新的消息使用.first

爲了避免N + 1查詢問題,請確保您加載相關的記錄:

@messages.eager_load(:recipient, :sender) 

當迭代(一個一般)使用的關聯,而不是IDS。千萬別像User.find(message.to_id)這樣會造成N + 1查詢問題。

<% @messages.each do |message| %> 
    <p><b><%= message.recipent.name %></b></p> 
    <p> 
    <% if message.read? %> 
     <%= link_to message.content, pm_path(message.recipient) %> 
    <% else %> 
     <b><%= link_to message.content, pm_path(message.recipient) %></b> 
    <% end %> 
    </p> 
<% end %>