【发布时间】:2020-06-10 12:20:32
【问题描述】:
我将 ActiveAdmin gem 与 Pundit(和 Rolify)gem 一起使用。
这就是我编写策略的方式(取自:https://github.com/activeadmin/activeadmin/blob/master/spec/support/templates/policies/application_policy.rb):
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def show?
scope.where(id: record.id).exists?
end
def create?
user.has_role?(:staff, record.company)
end
def update?
scope.where(id: record.id).exists?
end
def destroy?
scope.where(id: record.id).exists?
end
def destroy_all?
true
end
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.admin?
scope.all
else
company_ids = Company.with_role(:staff, user).map(&:id)
scope.where(company_id: company_ids)
end
end
end
end
这会导致每次scope.where(id: record.id).exists? 进行 N+1 次查询。在索引页上,为表中的每条记录调用show?、update? 和destroy?。
在这种情况下如何避免 N+1 查询?
我正在尝试:
1) 包括/预加载角色与用户一起调用current_user
2)我正在尝试记忆scope 或使用一些数组方法来防止使用where 和exists? 方法访问数据库。但是scope.find 仍然对每个新行进行 db 查询。
谢谢!
【问题讨论】:
标签: activeadmin pundit rolify