ruby-on-rails - 如何避免 N+1 查询并在 Active Admin 表单上执行预加载

标签 ruby-on-rails activeadmin formtastic

我正在经历N+1 query problemActive Admin ( Formtastic ) 形式。当加载与 belongs_to 关联对应的选择输入时,会发生查询。关联模型上的 display_name 引用另一个 belongs_to 关联。以下是模型关系:

:user 
   |-- belongs_to :alum 
                     |-- belongs_to :graduation_class
                                                   |-- year

以下是模型的相关部分:

app/models/user.rb

class User < ApplicationRecord
  ...
  belongs_to :alumn, optional: true, touch: true
  ...
end

app/models/alumn.rb

class Alumn < ApplicationRecord
  belongs_to :graduation_class, touch: true
  delegate :year, to: :graduation_class
  has_many :users
  ...
  def display_name
    "#{year}: #{last_name}, #{first_name} #{middle_name}"
  end
  ...
end

这是相关的事件管理类:

app/admin/user.rb

ActiveAdmin.register User do
  ...
  includes :alumn, alumn: :graduation_class
  ...
  form do |f|
    f.inputs do
      f.input :alumn  # This is causing the N+1 query
      ...
    end
  end
  ...
end

f.input :alumn 选择字段的生成导致对 graduation_class 进行 N+1 查询。这是因为Formtastic通过调用 alumn.display_name 生成选择选项,后者又调用关联的 graduation_class 上的 year 方法。

我的问题是,如何以这种形式预先加载graduation_class? Active Admin 类中的 includes :alumn, alumn: :graduation_class 似乎不起作用。

更新:

我可以从服务器日志中看到,GraduationClass正在加载,但它仍然没有消除N+1查询:

GraduationClass Load (0.6ms)  SELECT "graduation_classes".* FROM "graduation_classes"

最佳答案

我最终通过在 admin 字段上构建自定义集合解决了这个问题。相关代码如下:

app/admin/user.rb

ActiveAdmin.register User do
  ...
  includes :alumn, alumn: :graduation_class
  ...
  form do |f|
    f.inputs do
      f.input :alumn, as: :select, 
        collection: Alumn.includes(:graduation_class).where(...)
                      .collect { |a| [ a.display_name, a.id ] }
      ...
    end
  end
  ...
end

它仍然会导致额外的查询,但速度要快得多。

关于ruby-on-rails - 如何避免 N+1 查询并在 Active Admin 表单上执行预加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47065331/

相关文章:

ruby-on-rails - ActiveAdmin 有条件地显示列

ruby-on-rails-3 - Activeadmin 可以授权错误

ruby - 配置Active Admin的标签has_many

forms - cocoon gem 安装/使用?

ruby-on-rails - 如何在 ActiveAdmin 中使用 ActiveStorage `has_many_attached` 编辑多个附加图像

ruby-on-rails - RSpec 测试所有模型是否respond_to 属性

ruby-on-rails - 无法访问postgis的方法

ruby-on-rails - 使用 Rails 4 对象将 PSQL 查询转换为工作

ruby-on-rails - 如何将redirect_to() 与rails 3 中当前params[] 数组中的所有内容一起使用?

ruby-on-rails - 如何为 postgres jsonb 字段添加事件管理字段