ruby-on-rails 在ActiveAdmin sql查询中快速加载关联模型

nkkqxpd9  于 2023-01-14  发布在  Ruby
关注(0)|答案(5)|浏览(143)

我有一个ActiveAdmin索引页

ActiveAdmin.register Bill

我正在尝试显示指向关联模型的链接

index do
  column "User" do |bill|
   link_to bill.user.name, admin_user_path(bill.user)
  end
end

但是我遇到了N+1查询问题--有一个查询要获取每个用户。
有没有一种方法可以快速加载账单的用户?

0x6upsns

0x6upsns1#

方法是覆盖scoped_collection方法(如Jeff Ancel的回答所述),但调用super来保留现有的作用域,这样就可以保留ActiveAdmin应用的所有分页/过滤,而不是从头开始。

ActiveAdmin.register Bill do
  controller do
    def scoped_collection
      super.includes :user
    end
  end

  index do
    column "User" do |bill|
     link_to bill.user.name, admin_user_path(bill.user)
    end
  end
end

http://activeadmin.info/docs/2-resource-customization.html的官方文档所述

vpfxa7rd

vpfxa7rd2#

在不同的帖子上有一个答案,但它很好地描述了你需要在这里做什么。

controller do
    def scoped_collection
      Bill.includes(:user)
    end
  end

在这里,你需要确保你遵循scope,所以如果你的控制器是scope_to'ed,那么你需要用scope_to'ed参数替换上面的模型名。

gwbalxhn

gwbalxhn3#

当时的答案是正确的,但ActiveAdmin现在支持使用更方便的语法进行快速加载:

ActiveAdmin.register Bill do
  includes :user
end

请参阅resource customization的文档

jutyujz0

jutyujz04#

重要编辑提示:以下内容实际上是错误的,请查看评论中的解释。但是我保留这个答案,因为似乎我不是唯一一个被指南弄糊涂的人,所以也许其他人会发现它有用。

我假设

class Bill < ActiveRecord::Base
  belongs_to :user
end

因此,根据RoR指南,它已经是急切加载的:
不需要用途:include进行直接关联-也就是说,如果您有Order belongs_to:customer,那么在需要时会自动加载客户。
如果是真的,您应该检查您的SQL日志(我自己也不知道,我只是在验证关于:include的一些内容,以便在看到此消息时回答您......请告诉我)

nc1teljy

nc1teljy5#

我发现scoped_collection会加载所有条目,而不仅仅是你正在显示的页面的条目。我认为一个更好的选择是apply_collection_decorator,它只会加载你正在有效显示的条目。

controller do
  def apply_collection_decorator(collection)
    collection.includes(:user)
  end
end

相关问题