【问题标题】:Rails Display only last private message from user at the inboxRails 仅在收件箱中显示来自用户的最后一条私人消息
【发布时间】:2017-10-14 09:15:39
【问题描述】:

我创建了一个私人消息系统,但收件箱出现问题。 我想创建一个常规收件箱,您可以在其中查看所有对话。 我试图做某事,但我得到了用户收到的所有消息的结果,但我只想显示每个对话的最后一条消息。

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

希望我清楚并提前感谢您。

【问题讨论】:

    标签: ruby-on-rails message private inbox


    【解决方案1】:

    试试这个

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

    【讨论】:

      【解决方案2】:

      如果您正确设置关联,这很简单:

      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)
      

      在迭代时(通常)使用关联而不是 id。永远不要做像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 %>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        • 2019-09-23
        相关资源
        最近更新 更多