punditでRailsアプリに認可の仕組みを追加する
はじめに
ログインするユーザごとに利用可能な機能を取捨選択したい、といった要望は非常にありきたりなものです。これを実現するgemも数多く存在しています。そのなかで最も潮流にあるのがpunditというgemです。
ライバルにcancancanというgemもございますが、こちらを使われる方は段々と減ってきております。特別な理由がない限り、punditを利用しておいたほうが、世間的には好ましく受け止めてもらえるのではないでしょうか。
実装
punditをインストールします。
gem install pundit
モジュールをincludeします。
ジェネレータが用意されているので、これを実行します。
bundle exec rails g pundit:install
すると、app/policiesに認可関連のコードを配置するディレクトリが作成されます。punditではpolicyと呼ばれる枠組みの中で、コントローラーとアクションに基づいて、認可の是非を決定します。
呼び出しにはautholizedメソッドを利用します。
@post = Post.find(params[:id])
authorized @post
認可されていない処理が行われた際には、こちらで例外(Pundit::NotAuthorizedError)が投げられます。最低限、ApplicationControllerのrescue_fromでキャッチしてforbidden画面を出しておけば体裁は整うと思います。
また、indexアクションではpolicy_scopeメソッドを利用します。
@posts = policy_scope(Post)
こちらはscopeクラス内でresolveメソッドとして定義した処理が呼ばれます。
認可関連のコードは、人によってコードの置き場所が違ったり、書き方が違ったりと、プロジェクトのコードの可読性を下げる大きな要因になっているかと存じます。それを統一的なディレクトリ構成、記述方式で統一できるpunditは、とても素晴らしいgemだと思います。