Pundit
はじめに
こんにちは!大ちゃんの駆け出し技術ブログです。
最近は朝投稿が多いのでわりと朝活成功できています。
今日はRUNTEQの応用編で学習したgemの「Pundit
」について発信しようと思います!
認可とは
Pundit
は"認可"の設定を効率よく行うためのgemです。
ん?認可とは何ぞや?
あまり聴き慣れない言葉ですよね。
認可というのは とある特定の条件に対して、リソースアクセスの権限を与えること
引用: https://dev.classmethod.jp/articles/authentication-and-authorization/
認可されることを具体例として管理者ページへのアクセスを使って説明すると
とある条件が「ユーザーが管理者ユーザーか」とであるとき、管理者ユーザーであれば管理者ページ(リソース)にアクセスする権限が与えられること」となります。
逆に一般ユーザーは管理者ページへのアクセスができないです。これが認可されないということになります。
Punditの導入
Gemfileに追記してbundle install
# Gemfile gem "pundit"
$ bundle ・ ・ Fetching pundit 2.1.0 Installing pundit 2.1.0
アプリケーションコントローラに Pundit
をinclude
します。
class ApplicationController < ActionController::Base include Pundit end
次に下記コマンドを実行します。
$ rails g pundit:install Running via Spring preloader in process 47291 create app/policies/application_policy.rb
すると行数の多いファイルが作成されました。
# app/policies/application_policy.rb class ApplicationPolicy attr_reader :user, :record def initialize(user, record) @user = user @record = record end def index? false end def show? false end def create? false end def new? create? end def update? false end def edit? update? end def destroy? false end class Scope attr_reader :user, :scope def initialize(user, scope) @user = user @scope = scope end def resolve scope.all end end end
app/policies
配下にファイルが置かれたように、Punditのファイルは全てこのディレクトリ配下に格納されます。application
とあるように、こちらのファイルにはPunditのファイル全てに共通する内容を書きます。application_controller.rb
などと同じですね。
しかし、今回はよりPunditを理解するために固有の認可システムを作成します。例えば、このアプリケーションにBoard(掲示板)というモデルがあるとします。
このBoardを操作するにあたり、board_controller.rb
のupdate
アクションに管理者ユーザーのみが行えるようにするとします。実装するためにapp/policies
配下にboard_policy.rb
を作成します。
# app/policies/board_policy.rb class BoardPolicy attr_reader :user, :board def initialize(user, post) @user = user @post = post end def update? user.admin? end end
次にboard_controller.rb
のupdate
アクションにauthorize
メソッドをインスタンス変数を引数に使用します。
# app/controllers/boards_controller.rb def update authorize @board if @board.update(board_params) redirect_to @board, success: t('defaults.message.updated', item: Board.model_name.human) else flash.now['danger'] = t('defaults.message.not_updated', item: Board.model_name.human) render :edit end end
ここで何が行われるのかというと、update
アクションが実行時(掲示板を更新した時)、@board
からauthorize
メソッドはboard_policy.rb
があることを推測します。そして、現在実行されているアクション名に?が追加されたメソッドを探します。今回でいうと、board_policy.rb
のupdate?
メソッドです。
def update? user.admin? end
そしてuser.admin?
がture
を返さなければ、例外が発生します。これで管理者ユーザーのみがupdateアクションを実行することができ、一般ユーザーはupdateアクションを実行できなくなりました。これが認可を定義するPunditの力です!
終わりに
今回は簡単にざっくりとPunditを紹介しました!
1からアプリを実装しようとすると、ログイン機能を実装したりしなければならないので、今回は既存のアプリで試しました。みなさんもお手元の簡単なアプリで是非Punditを実装してみてください!
以上、大ちゃんの駆け出し技術ブログでした!