Tom*_*nda 5 ruby-on-rails formtastic activeadmin
我在Active Admin ( Formtastic ) 表单中遇到N+1 查询问题。当加载与关联对应的选择输入时,会发生查询。关联模型上的 引用另一个关联。以下是模型关系:belongs_todisplay_namebelongs_to
:user
|-- belongs_to :alum
|-- belongs_to :graduation_class
|-- year
Run Code Online (Sandbox Code Playgroud)
以下是模型的相关部分:
应用程序/模型/user.rb
class User < ApplicationRecord
...
belongs_to :alumn, optional: true, touch: true
...
end
Run Code Online (Sandbox Code Playgroud)
应用程序/模型/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
Run Code Online (Sandbox Code Playgroud)
这是相关的 Active Admin 类:
应用程序/管理/用户.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
Run Code Online (Sandbox Code Playgroud)
select 字段的生成f.input :alumn导致了 上的 N+1 查询graduation_class。这是因为Formtastic通过调用生成选择选项,alumn.display_name而该调用又调用year关联的graduation_class.
我的问题是,我怎样才能graduation_class以这种形式急切加载?Active Admin类includes :alumn, alumn: :graduation_class中的 似乎不起作用。
更新:
我可以从服务器日志中看到正在GraduationClass加载,但它仍然没有消除N+1查询:
GraduationClass Load (0.6ms) SELECT "graduation_classes".* FROM "graduation_classes"
Run Code Online (Sandbox Code Playgroud)
我最终通过在现场构建自定义集合解决了这个问题admin。这是相关代码:
应用程序/管理/用户.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
Run Code Online (Sandbox Code Playgroud)
它仍然会导致额外的查询,但速度要快得多。