コンテンツにスキップ

rigor-pundit

Punditのauthorizepolicypolicy_scope呼び出しを、静的に発見したポリシーインデックスに照らして検証します。ポリシークラスが存在しなければならず、authorize(record, :action)のアクションはそのポリシー上で定義された<action>?述語に対応していなければなりません。ソースのみを読み取り、Punditのランタイム依存はありません。

rigortypeにバンドルされて配布されます。plugins:の下で有効化します。

plugins:
- rigor-pundit
app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
def show?; true; end
def update?; true; end
def destroy?; true; end
end
authorize(Post, :show) # info: PostPolicy#show? に解決される
authorize(Post, :destory) # error: PostPolicy#destory? は定義されていない(:destroy? の誤りでは?)
authorize(Comment, :edit) # error: ポリシークラス CommentPolicy が存在しない(… の誤りでは?)
ルール重大度発火するとき
plugin.pundit.policy-callinfoauthorizepolicypolicy_scope呼び出しが、発見済みのポリシーに解決された
plugin.pundit.unknown-policy-classerrorレコードがインデックスにエントリーのない<Type>Policyにマッピングされる(誤り候補の提示付き)
plugin.pundit.unknown-policy-methoderrorポリシーは存在するが、:actionに対応する<action>?述語がない(既知の述語の一覧+誤り候補の提示付き)
plugin.pundit.load-errorwarningポリシーの発見に失敗した(パース/読み取りエラー) ── ファイルごとに1回

レコードは、定数名または推論されたNominal[T]によってポリシーにマッピングされます(PostPostPolicy)。:updateupdate?に正規化されます。アクションを伴わないauthorize(record)は、ポリシークラスのみを検証します(アクションはコントローラーのランタイムに束縛されるため)。

plugins:
- gem: rigor-pundit
config:
policy_search_paths: ["app/policies"] # デフォルト
policy_base_classes: ["ApplicationPolicy"] # デフォルト
  • 直接のスーパークラスとの一致のみclass AdminPostPolicy < AdminPolicyAdminPolicy < ApplicationPolicyの場合)は、AdminPolicypolicy_base_classesに追加しない限り発見されません。
  • 述語メソッドのみ?で終わらないメソッド、およびdefine_methodで構築された述語やconcernから継承された述語は対象外です。
  • 型なしのレコードは素通りするlocalに推論されたNominal[T]がない場合、authorize(local, :show)は検証されません。
  • Scopeポリシーは、クラスの存在については検証されますが、Scope#resolveについては検証されません。

ポリシーの発見器/インデックス、およびこのプラグインが行使する契約(contract)サーフェスは、プラグインのREADMEにあります。プラグインの書き方については、examples/rigor-plugin-authorスキルを参照してください。

© 2026 TypedDuck. Licensed under CC BY-SA 4.0.