【问题标题】:Rails ActiveRecord find a table attribute's value given conditions in 2 tablesRails ActiveRecord 在 2 个表中查找给定条件的表属性值
【发布时间】:2017-02-25 08:35:08
【问题描述】:

我有两张桌子:

  1. 一个会话表,其中包含一个会话列表及其 ID(以及与每个会话关联的两个用户 ID('recipient_id' 和 'sender_id')。
  2. 包含与现有对话之一相关的消息的消息表。每个 Message 实例都包含一个布尔属性“read”(默认为 false),用于显示对话中是否有任何未读消息。

所以 Conversation has_many :messages 和 Message belongs_to :conversation

我的目标是检查 current_user 是否有任何未读消息(在他现有的任何对话中)以显示一般警报。 到目前为止,我已经设法为每个对话显示一个警报,但我正在努力寻找一种有效的方法来实现一个通用的。

我最初的方法是:

  1. 在每个当前用户的对话中查找最后一条消息。
  2. 评估最后的每条消息是否都是由当前用户发送的,如果 read == false。
  3. 如果最后一条消息满足这些条件,则返回 true。

这翻译成如下代码:

  @conversations = current_user.conversations
  @unread = []
  if @conversations.exists?

      @conversations.each do |conversation|
        if conversation.messages.exists?
          if conversation.messages.last.user_id != current_user.id && conversation.messages.last.read == false
            @unread << true
          end
        end
      end
  end

  @unread.include?(true)
end

我是一个相当新的编码,但它似乎是一种非常低效的方法,必须遍历所有 current_users 对话并创建一个数组来检查它是否有任何“真实”值。

我会自己遍历消息,但一个实例只有发件人的 user_id,所以如果我不将它与对话模型链接,则无法知道是否有消息发送给他。

您能否通过更合适的 Active Record 查询或更好的方法来提供一种有效的方法来实现此目的。

顺便说一句,不确定是否重要,但我在开发环境中使用的是 postgresql。

谢谢

【问题讨论】:

    标签: ruby-on-rails postgresql activerecord


    【解决方案1】:

    您可以通过以下方式获取current_userconversation id:

    conv_ids = current_user.conversations.pluck(:id)
    

    进行查询以获得满足您所需条件的消息计数,例如:

    unread_count = Message.where(convsersation_id: conv_ids, read: false).where.not(user_id: current_user.id).count
    

    如果unread_count &gt; 0 则可以显示警报

    我假设所有消息在读取后都会获得 read :true 值,因此即使会话中最后一条消息以外的任何其他消息具有 read :false,此查询也会返回 true。

    PS:我还没有测试过查询,所以请检查并在必要时进行调整。如果我在这里遗漏任何内容,请在评论中提出。

    【讨论】:

    • 非常感谢萨扬。这说得通。让我试一试,考虑一下,一有消息就会回复你。
    猜你喜欢
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    相关资源
    最近更新 更多