2017-10-14 9 views
0

J'ai créé un système de messagerie privé mais j'ai des problèmes avec la boîte de réception. Je veux créer une boîte de réception régulière où vous pouvez voir toutes vos conversations. J'ai essayé de faire quelque chose mais j'obtiens un résultat de tous les messages que l'utilisateur a reçu mais je veux afficher seulement le dernier message de chaque conversation.Rails Afficher uniquement le dernier message privé de l'utilisateur à la boîte de réception

SQL: J'obtenu table des messages avec id, user_id (int), to_id (int), le contenu (texte), lire (Boolean).

Messages Contrôleur:

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

Vue:

<% @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 %> 

Espoir Je suis clair et je vous remercie à l'avance.

Répondre

0

essayez celui-ci

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

Travail de dosage .... –

0

Si vous configurez les associations correctement, il est trivial:

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) 

La clé pour obtenir tout message entre les utilisateurs est:

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

Mais vous devriez envisager de créer un modèle de conversation pour les rejoindre à la place.

L'appel .last obtiendra le plus ancien enregistrement puisqu'il est dans l'ordre décroissant. Si vous voulez l'utiliser le plus récent message .first

Pour éviter N + 1 numéro de requête assurez-vous que vous chargez les enregistrements associés:

@messages.eager_load(:recipient, :sender) 

Lorsque itérer (un en général) utilisent les associations au lieu de ids. Ne jamais faire des choses comme User.find(message.to_id) car cela entraînera un problème de requête 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 %>