【问题标题】:Rails eager load custom has_many on indexRails 急切地在索引上加载自定义 has_many
【发布时间】:2018-05-03 17:33:59
【问题描述】:

Ruby 2.1、Rails 3.2
我的项目模型中有这种关系

scope :active, -> { where( deleted_at: nil ) }
has_many :foremen, class_name: "ProjectsUser",  conditions: ['current_foreman = 1']

在控制器中:

@projects = Project.includes(:foremen).active

生成此 SQL

ProjectsUser Load (3.3ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` IN (122, 130, ...etc.) AND ( current_foreman = 1)

但是当我在视图中调用关系时...

<% @projects.each do |project| %>
  <%= project.foremen.current_foreman %>
<% end %> 

它每次都会运行另一个 SQL 查询。

ProjectsUser Load (2.5ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` = 122 AND (current_foreman = 1 )
ProjectsUser Load (2.5ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` = 130 AND (current_foreman = 1 )
ProjectsUser Load (2.5ms)  SELECT `projects_users`.* FROM `projects_users` WHERE `projects_users`.`project_id` = 151 AND (current_foreman = 1 )
etc...

我是不是误会了什么?这些记录不应该已经加载了吗?
我该怎么写才能只为ProjectsUser 运行一个查询?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 eager-loading


    【解决方案1】:

    我认为您在项目循环中调用它是正常的。

    【讨论】:

      【解决方案2】:

      所以我做了更多的挖掘,发现我的逻辑是正确的;这不会自行生成任何额外的查询。问题是我在对象上调用的方法。

      以下不会调用任何查询:

       project.current_foremen_and_managers.select{|f| f.current_foreman}.sort_by{ |f| f.added_at}.first
      

      但是,当您将额外的逻辑移动到关联类中的方法中时,它确实会生成更多的 sql

      class ProjectUser < ActiveRecord::Base
        def self.find_first_foreman
          select{|f| f.current_foreman}.sort_by{ |f| f.added_at}.first
        end
      end
      

      如果我调用这个方法,它会运行一个查询

      project.current_foremen_and_managers.find_first_foreman
      

      我不完全确定为什么会发生这种情况,如果有人有解释我很想听听。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多