gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 01:53:40 27 4
gpt4 key购买 nike

我正在经历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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com