我定义了文档中所述的Pundit策略“CompanyPolicy”,scopez给出了预期的结果(on:index)但是我尝试使用公司模型实例时遇到异常:
*** NameError Exception: undefined local variable or method `company' for #<CompanyPolicy:
这是CompanyPolicy.rb
class CompanyPolicy < ApplicationPolicy
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.system_admin?
scope.all
else
Company.none
end
end
end
def new?
user.system_admin? ? true : false
end
def edit?
user.system_admin? ? true : false
end
def show?
user.system_admin? ? true : false
end
def destroy?
internal_name = Rails.application.secrets.internal_company_short_name
# do not destroy the internal company record
user.system_admin? && (company[:short_name] != internal_name ) ? true : false
end
end
我从公司控制器检查它
def destroy
authorize @company
#@company.destroy
....
end
为什么(公司[:short_name]错了?
如果我查看Pundit文档,PostPolicy,scope和post.published的示例是类似的......
class PostPolicy < ApplicationPolicy
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.admin?
scope.all
else
scope.where(:published => true)
end
end
end
def update?
user.admin? or not post.published?
end
end
答案 0 :(得分:0)
刚刚发现应该使用@record而不是公司 (阅读与范围相关的问题:Implementing scopes in Pundit)
但我不明白为什么Pundit doc没有提及它,仍然使用像&#39; post&#39;对于PostPolicy ...... 有人可以启发我们吗?
答案 1 :(得分:0)
Pundit对这个类做出如下假设:
- 该类与某种模型类具有相同的名称,仅以“Policy”一词为后缀。
- 第一个参数是用户。在您的控制器中,Pundit将调用current_user方法来检索要发送到此的内容 论点
- 第二个参数是某种模型对象,您要检查其授权。这不需要是一个 ActiveRecord甚至是ActiveModel对象,它可以是任何东西 真。
- 该类实现了某种查询方法,在这种情况下更新?通常,这将映射到特定的名称 控制器动作。
真的。
通常,您希望继承自创建的应用程序策略 生成器,或设置自己的基类继承自:
class PostPolicy < ApplicationPolicy def update? user.admin? or not record.published? end end
在生成的ApplicationPolicy中,模型对象名为
record
。