4

当我创建一个新的脚手架时,我想使用它的默认权威配置,它在app/policies/application_policy.rb. 如果不创建一个model_name_policy.rb,我总是会unable to find policy出错。

当我没有为特定模型设置规则时,如何使用默认值?

4

3 回答 3

2

最简单的方法可能是从Pundit::NotDefinedErrorraise by中解救出来Pundit::PolicyFinder#policy!

鉴于您的默认策略:

# app/policies/application_policy.rb:
ApplicationPolicy = Struct.new :user, :record do
  def index?
    true
  end

  def show?
    true
  end

  # ... other sensible defaults

end

假设您在 Rails 控制器中使用它:

# app/controllers/application_controller.rb:
class ApplicationController
  include Pundit

  # ...

  private

  def policy(record)
    super
  rescue Pundit::NotDefinedError
    ApplicationPolicy.new pundit_user, record
  end
end

免责声明:我还应该指出,通常不赞成创建隐式默认策略。除了最简单的情况或最悲观的默认值(全部为假)外,过于宽松的政策很容易溜走。

于 2016-02-04T22:38:01.497 回答
1

我不知道没有为每个模型创建策略的方法,但是您可以创建一个从应用程序策略继承的策略。你ApplicationPolicy可能看起来像这样:

class ApplicationPolicy
  def index?
    true
  end

  def show?
    true
  end

  ... More actions ...
end

当您设置新的脚手架时,只需添加一个从您的应用程序策略继承的空白策略:

class UserPolicy < ApplicationPolicy

end

动作将继承自ApplicationPolicy. 如果需要,您始终可以覆盖默认值:

classUserPolicy < ApplicationPolicy
  show?
    @user.admin == true ? true : false
  end
end

希望这可以帮助!

于 2014-12-29T19:28:07.940 回答
1

我使用权威 2.1.0

authorizeorpolicy_scope方法用于PolicyFinder查找策略类,因此policy仅当您使用authorizepolicy_scope执行该操作时才覆盖方法是没有用的。我使用以下方式在我的应用程序中设置默认策略:

Pundit::PolicyFinder.class_eval do
  def policy
    klass = find(object)
    (klass.is_a?(String) ? klass.safe_constantize : klass) || DefaultPolicy # set a default policy
  end
end

也许这不是最好的方法(它粗暴地修改了原始库中的方法,违反了库的设计),但对我来说已经足够了。

愿它有所帮助!

于 2020-08-05T02:17:44.417 回答