🐥

Punditの要点を理解する

2022/11/30に公開

3行まとめ

  • Punditを大まかに理解したい
  • PunditはRailsアプリなどRubyのプログラムに認可の仕組みを与える
  • 主な二種類の使い方:ページの実行の可否を判定したり、scopeの絞り込みを出し分けたり

Punditとは

これ。
https://github.com/varvet/pundit#headless-policies

Pundit provides a set of helpers which guide you in leveraging regular Ruby classes and object oriented design patterns to build a simple, robust and scalable authorization system.

PunditはRubyで用いられる認可(authorization)のためのgemです。
Railsで用いられることが多いものの、必ずしもRailsでしか使えないということはないのですね。

細かい使い方は分かるものの、仕組みというか、全般的な流れがよく理解できていなかったので、ここで改めて READMEを読みながら頭の整理をしたいと思います。

READMEを読んで概要を掴む

Punditには大まかに考えて2つの用途があるといえるでしょう。概念の整理なので、言葉遣いの多少の不正確さは気にしないことにします。

  1. ページの表示の可否の認可(authorizeメソッドを使う)
  2. メソッドの中での、認可による処理の分岐(Scopeクラス、resolveメソッドを使う)

ページの表示の可否の認可(authorizeメソッドを使う)

Railsがリクエストを受けて、とあるcontrollerのとあるmethodに到達したとします。ユーザーの属性などで、そのメソッドの処理を実行するか否かを判定します。例えばindexメソッドが呼び出されたとしましょう。
Policyクラスを作って、index?メソッドに認可の条件を記述します。
controller側ではauthorizeメソッドを呼び出し、そのPolicyクラスを読み込ませると、index?メソッドの条件に応じて認可の可否(言葉遣いがあっているかわからない)を判定してくれます。

登場人物

  • controller
    リクエストに応じてメソッドが呼び出される。authorizeメソッドを書いて、対応するpolicyクラスを呼び出す。もう少し詳しくいうと認可の対象になるuserオブジェクトを渡して、policyクラスのインスタンスを作る。
    特に条件を指定しなければ、controller名に対応したpolicyファイルを呼び出すし、明示して指定することもできる。
  • Policyクラス
    controllerからauthorizeメソッドで呼び出されてインスタンスを作成する。認可の条件を記述する。

メソッドの中での、認可による処理の分岐(Scopeクラス、resolveメソッドを使う)

scopeという名の通り、ActiveRecordを意識してそうな感じですが、
先述した話がページの表示の可否を判定するものだとすると、今回は処理の分岐です。
例えばREADMEにもある通り、 adminであれば全ての情報を、そうでなければ一部の情報を返す、というような分岐を作りたいとします。
その時にPolicyファイルの中にScopeというクラスを作り、その中のresolveというメソッドに分岐処理を書きます。scopeという引数に、ActiveRecordが渡ってくるイメージです。
controllerの方では、policy_scopeという関数を呼び出すと、認可を踏まえたresolveメソッドを呼び出してくれます。

登場人物

  • controller
    policy_scopeを呼び出す。
  • Policyクラス内のScopeクラス
    controllerでpolicy_scopeを呼び出すと、Scopeクラス内のresolveメソッドが呼び出されます。モデルやActiveRecord::Relationが渡ってきて、そこに認可による処理の分岐を作る。

まとめ

Punditにはそこそこ苦手意識があったのですが、いざ丁寧にREADMEを読んで一つ一つ整理していくと、結構シンプルな機能のgemなのかな?という印象も持ちました。
次は、もう少し踏み込んでPunditのソースコードも読んでみて仲良くなれたらいいなと思います。

Discussion