【问题标题】:Include column from another table in a query (rails activerecord)在查询中包含来自另一个表的列(rails activerecord)
【发布时间】:2020-02-28 12:04:25
【问题描述】:

在对话控制器中,我有以下内容:

  def users_with_existing_conversations
    authorize! :users_with_existing_conversations, Conversation

    @users = User.accessible_by(current_ability, :index_conversations)

    @users = @users.where(id: Conversation.select(:sender_id))
                    .or(@users.where(id: Conversation.select(:recipient_id)))

    @users = @users.search(params[:query]) if params[:query].present?


    @users = sort_and_paginate(@users)
    set_meta_tags title: "Existing Conversations", reverse: true
  end

在用户模型中,我有这个has_many relaitonship:

  has_many :sender_conversations, class_name: 'Conversation', foreign_key: "sender_id", dependent: :destroy
  has_many :recipient_conversations, class_name: 'Conversation', foreign_key: "recipient_id", dependent: :destroy

在控制器模型中,我有 belongs_to 关联:

 belongs_to :sender, foreign_key: :sender_id, class_name: 'User'
  belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User'

回到控制器,@users 对象正在被渲染到视图中。我需要会话表中的一个附加列,即last_updated 列。

所以基本上我想从conversation 表中向@users 添加一个键值对

我尝试过类似的东西

@users.each do |user|
user[:latest_conversation] = Conversation.where(sender_id: user.id)
end

导致can't write unknown attribute latest_conversation

我也尝试过类似的测试查询

@testUsers = @users.sender_conversations

导致undefined method sender_conversations

正如您在上面看到的,我的模型中有关联。文档显示了示例,我认为这会起作用

在我看来,我有:

 <% @users.each do |user| %>
  <tr class="table__row" onclick="window.location.href = '/conversations?user_id=<%= user.id %>'">
    <td><%= user.name %></td>
    <td><%= user.surname %></td>
    <td><%= user.email %></td>
    <td><%= user.company_name.present? ? user.company_name : "N/A" %></td>
    <td><%= user.role.capitalize %></td>
    <td><%= user.created_at.try(:strftime, '%b %d, %Y') %></td>
    <td><%= user.latest_conversation %></td>
    <td class="table__more">
      <%= link_to "Show details", conversations_path(user_id: user.id), class: 'table__row__details button button--tertiary button--tertiary-small' %>
    </td>
  </tr>
  <% end %>

所以我真的很想在用户循环中访问@user.latest_conversation

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    为什么不在 User 模型上定义一个方法?

    class User < ...
    
      def latest_conversation
        sender_conversations.last
      end
    

    【讨论】:

      【解决方案2】:

      app/models/user.rb:

      class User < ApplicationRecord
        # ...
      
        # combines both "sender" and "recipient" conversations
        # you can also move this into a `has_many :conversations` but you'll need 
        # to `unscope`; see @dre-hh answer here https://stackoverflow.com/questions/24642005/rails-association-with-multiple-foreign-keys
        def conversations
          Conversation.where(sender_id: id).or(
            Conversation.where(recipient_id: id)
          )
        end
      
        ## instead of above, try the commented code below
        ## Untested, but I think this should also work
        # def conversations
        #  sender_conversations.or(recipient_conversations)
        # end
      
        # get the latest conversation ordered by "last_updated"
        def latest_conversation
          conversations.order(last_updated: :desc).first
        end
      end
      

      【讨论】:

      • 完美!感谢您对发件人或收件人进行检查。这正是我所需要的
      • 能否再问一个问题?我想按 user.latest_conversation 排序。但是用户表上当然不存在该列
      • @millman2394 当然;没问题! :) 您需要将def conversation 移动到has_many :conversations 中(请参阅上面的链接,了解如何操作)。现在它是一个关联,你现在可以做@users = @users.includes(:conversations).order('conversations.last_updated' =&gt; :desc)
      • 谢谢!我会尝试根据 dre-hh 的回答来弄清楚。我是 ruby​​ 和 rails 的新手。负责完成别人的项目哈哈
      • @millman2394 祝你好运! :) 我将您推荐给该链接的原因是因为我对它的工作原理不太熟悉。但是,如果我做对了,你可以这样做:has_many :conversations, -&gt; (user) { unscope(where: :user_id).where('sender_id = :id OR recipient_id = :id', id: user.id) }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 2012-11-09
      相关资源
      最近更新 更多