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だと思います。

Rails

Posted by poison