2017-10-14 17 views
0

비공개 메시지 시스템을 만들었지 만받은 편지함에 문제가 있습니다. 모든 대화를 볼 수있는 일반받은 편지함을 만들고 싶습니다. 나는 어떤 일을 시도했지만 사용자가 얻은 모든 메시지의 결과를 얻지 만 각 대화의 마지막 메시지 만 표시하려고합니다.레일받은 편지함의 마지막 비공개 메시지 만 표시

SQL : ID가 user_id (int), to_id (int), 내용 (텍스트), 읽기 (부울) 인 메시지 테이블이 있습니다.

메시지 컨트롤러 :

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

취업 활동 .... –

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) 

것은 반복하는 (일반의)를 대신 식별자의 연결을 사용하는 경우. 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 %>