punditの質問についての回答
■Question
admin/oems_controller.rbの、
■Answer
①
対応関係をOemControllerは表現できている。
具体的にはAdmin権限であるかを認証対象としており、adminのみ通る構成になる。
②
before_actionにおける、index create / update destroyという組み分けと、
メソッドの別定義はRESTの概念の違い、URLにidをとるかどうかの違いによって生じる差分である。
③
punditの認証チェックメソッドであるauthorizeは、モデルクラスもインスタンスも両方を引数として取れるので、その違いはpunditにおいては吸収される。
下記に説明。
■
①before_action
アクセス制御の仕組み。
元々はログインユーザーと非ログインユーザーを分けるとかで使う処理。
管理者機能は特にアクセス制御が必要。
なので、当ファイルのbefore_actionで、アクションを行う前に実行するようにする。
ex)ログイン管理の簡単実装
■
②index create / update destroyの違い
(Railsを支える基本概念の整理(RESTfulやリソースなど)より
上記の中で、URLにおいて、
admin/oems_controller.rbの、
before_action :authorize_oem, only: %i[update destroy]は、policies/oem_policy.rbのOemPolicyクラスの、
- index
- create
- update
- create_organization
- edit_organization
- destroy
■Answer
①
対応関係をOemControllerは表現できている。
具体的にはAdmin権限であるかを認証対象としており、adminのみ通る構成になる。
②
before_actionにおける、index create / update destroyという組み分けと、
メソッドの別定義はRESTの概念の違い、URLにidをとるかどうかの違いによって生じる差分である。
③
punditの認証チェックメソッドであるauthorizeは、モデルクラスもインスタンスも両方を引数として取れるので、その違いはpunditにおいては吸収される。
下記に説明。
■
①before_action
アクセス制御の仕組み。
元々はログインユーザーと非ログインユーザーを分けるとかで使う処理。
管理者機能は特にアクセス制御が必要。
なので、当ファイルのbefore_actionで、アクションを行う前に実行するようにする。
ex)ログイン管理の簡単実装
class Admin:: < ApplicationController before_action :authorize ... private def authorize unless current.administrator redirect_to :admin_login end end
■
②index create / update destroyの違い
(Railsを支える基本概念の整理(RESTfulやリソースなど)より
上記の中で、URLにおいて、
- 個別的にidを取らないのが index create
- idを取るのが update destroy
この違いをもってして、
before_actionでの挙動の違い、
-----
authorize oem
....
@oem = oem.find(params[id])
authorize @oem
-----
という挙動の違いになっている。
(参考:挙動の対照表)
@oem = oem.find(params[id])
=>
get '/oem/:id', to: 'oem#show', as: 'oem'
■
③Railsのルーティングについて
namespace :admin do
resources :oems, only: [:index, :create, :update, :destroy]
は、
get "oems" => "oem#index"
post "oems" => "oem#create"
patch "oems/:id" => "oem#update"
delete "oems/:id" => "oem#destroy"
を一行で表現したもの。
only:[...]に記述のないshow,new,editは除く。
(Railsのルーティング)より
■
④%i[index create]について
これはシンボル配列のリテラルである。
実体として、[:index :create]である。
つまり、indexメソッド と createメソッドのことを指す。
また、%w[...]は文字列配列のリテラルである。
■
⑤Punditにおける関係性について
authorizeメソッドでは、、、
■punditについて
ベースファイルのApplicationPolicyの初期構成状態は、
クラスを拡張することで(OemPolicy < ApplicationPolicyとか)で、
設定することでホワイトリスト的に認証OK状態を定義している。
ちなみに初期セットアップの下記の部分
def create?
false
end
def update?
false
end
なので、newとcreate/editとupdateは相互依存関係にある。
■
OemPolicyファイルの中身を見てみると、
....
class OemPolicy < ApplicationPolicy
def index?
user.nttpc_administrator?
end
def create?
index?
end
def update?
index?
end
....
index?で、ユーザーがadminユーザーかどうかを確認している。
trueを返せば認証OK。
他のcreate?update?destroy?は、中身がindex?なので、
同様にユーザーがadminユーザーかどうかを確認している。
つまり、OemPolicyがチェックしている認証情報は、
ユーザーがadminユーザーかどうか、という一点のみであること。
authorizeメソッドについて
暗黙的には、current_user(現在のユーザー)とrecord(レコードorクラス)を引数にとって、その値を評価している。
■参考:pundit
(参考:挙動の対照表)
@oem = oem.find(params[id])
=>
get '/oem/:id', to: 'oem#show', as: 'oem'
■
③Railsのルーティングについて
namespace :admin do
resources :oems, only: [:index, :create, :update, :destroy]
は、
get "oems" => "oem#index"
post "oems" => "oem#create"
patch "oems/:id" => "oem#update"
delete "oems/:id" => "oem#destroy"
を一行で表現したもの。
only:[...]に記述のないshow,new,editは除く。
(Railsのルーティング)より
■
④%i[index create]について
これはシンボル配列のリテラルである。
実体として、[:index :create]である。
つまり、indexメソッド と createメソッドのことを指す。
また、%w[...]は文字列配列のリテラルである。
■
⑤Punditにおける関係性について
authorizeメソッドでは、、、
■punditについて
ベースファイルのApplicationPolicyの初期構成状態は、
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 end end endこれは、初期セットアップで、すべてのメソッドで認証拒否状態になっている。
クラスを拡張することで(OemPolicy < ApplicationPolicyとか)で、
設定することでホワイトリスト的に認証OK状態を定義している。
ちなみに初期セットアップの下記の部分
def create?
false
end
def update?
false
end
なので、newとcreate/editとupdateは相互依存関係にある。
■
OemPolicyファイルの中身を見てみると、
....
class OemPolicy < ApplicationPolicy
def index?
user.nttpc_administrator?
end
def create?
index?
end
def update?
index?
end
....
index?で、ユーザーがadminユーザーかどうかを確認している。
trueを返せば認証OK。
他のcreate?update?destroy?は、中身がindex?なので、
同様にユーザーがadminユーザーかどうかを確認している。
つまり、OemPolicyがチェックしている認証情報は、
ユーザーがadminユーザーかどうか、という一点のみであること。
authorizeメソッドについて
- authorize Oem
- authorize @oem
という記述があるが、クラスでもインスタンスでも両方とも値にとれる。
暗黙的には、current_user(現在のユーザー)とrecord(レコードorクラス)を引数にとって、その値を評価している。
■参考:pundit