Posted at

cancancanのload_resourceのまとめ

権限承認用にCanCanCommunity/cancancanを入れていましたが、load_resourceが多機能で、認証不要な場面でも使いたくなるものでした1


デフォルトの機能性

デフォルトでは、こんな動きをします。


app/controllers/items_controller.rb

class ItemsController < ApplicationController

load_resource
end

このように書いておくと、以下の動きをします。



  • newアクション→@itemItem.newをしたものが入り、なおかつ権限設定上必須となる値がセットされる


  • createアクション→newで行われる初期化処理にプラスして、paramsの解釈用に用意してあるメソッド(後述)を呼び出して@itemを変更する


  • indexアクション→@itemsItem.accessible_by(current_ability)が入る


  • showeditdestroy、基本7つ以外のアクション…@itemItem.find_by(params[:id])が入る


  • updateアクション…上のように@itemが回収された上で、paramsの解釈用に用意してあるメソッド(後述)を呼び出して@itemを変更する

これだけしてくれるので、アクション内で書くコードは大幅に減少します。newアクションなどは、空っぽになってしまうこともありえます。


自動で呼び出すparamsメソッド

以下のような優先順位で、存在するメソッドが呼び出されます。全てなければ何も起きません。



  1. load_resourceのオプションでparam_method: :method_nameのように指定した名前

  2. #{アクション名}_params

  3. #{リソース名}_params

  4. resource_params


カスタマイズする

もちろん、レールに乗っかってデフォルトの設定で使うのが楽なのは間違いないですが、そうは問屋が卸さない場面も多々あります。そのような場合は、自分で上書きすることもできます。


先に自分でロードする

一部のアクションだけ自分でロードしたい場合には、load_resourceの前にbefore_action@itemをセットすれば、load_resourceによるロードはバイパスされます。


ネストする

ネストしたリソースの場合、load_resourceを複数重ねることで両方をロードさせることができます。長くなりそうなので、詳しくは公式のWikiを見てください。


引数指定

load_resourceに引数を足すことで、デフォルトでは名前から暗黙に設定されていた変数やクラス名も、手動設定できます。



  • only:except:before_actionに付ける同様の引数のように、アクションごとにload_resourceを適用するかしないかを切り替えます。


  • through:through_associationshallow:singleton:parent:…リソースネスト関連のパラメーターです(詳細略)。


  • class:…モデルのクラスを文字列、あるいは定数で指定します。


  • instance_name:…インスタンス変数の名前を変更します(先頭の@は不要です)。コレクションの変数も、これの複数形になります。


  • find_by:…モデル1つの取得をfund_by_#{find_by}!メソッドで行うように切り替えます。


  • id_param:…モデルを特定する引数をparams[:id]以外に切り替えます。


  • collection:index以外の、コレクションを取得するアクションを指定します。


  • new:newcreate以外でモデルを新規作成するアクションを指定します。





  1. ただし、can :manage, Modelのようにきちんと素通しにする形でセットしておかないと、うまく動きません。