【Ruby on Rails: cancancan】canの旅 (ソースコードリーディング)第五回
ということで、cancancanのソースコードリーディング第五回はじめます。
前回まではコチラ
前回はControllerResourceクラスのadd_before_actionの引数まで見ていきました!
今回はControllerResource.add_before_actionの内部を扱っていきます。
require_relative 'controller_resource_loader.rb'
module CanCan
class ControllerResource # :nodoc:
include ControllerResourceLoader
def self.add_before_action(controller_class, method, *args)
options = args.extract_options!
resource_name = args.first
before_action_method = before_callback_name(options)
controller_class.send(before_action_method, options.slice(:only, :except, :if, :unless)) do |controller|
controller.class.cancan_resource_class.new(controller, resource_name, options.except(:only, :except, :if, :unless)).send(method)
end
end
def self.before_callback_name(options)
options.delete(:prepend) ? :prepend_before_action : :before_action
end
def initialize(controller, *args)
@controller = controller
@params = controller.params
@options = args.extract_options!
@name = args.first
end
def load_and_authorize_resource
load_resource
authorize_resource
end
end
end
*options = args.extract_options!
extract_options!で、optionsに、ハッシュで入った値が入ります。
下記の場合、:only => [:index, :show]がoptionsになりま-す!!
load_and_authorize_resource :only => [:index, :show]
*resource_name = args.first
resourvce_nameはargsの最初の要素。
下記の場合、:only => [:index, :show]がresource_name。
load_and_authorize_resource :only => [:index, :show]
*before_action_method = before_callback_name(options)
before_callback_nameは下記。
options.delete(:prepend) ? :prepend_before_action : :before_action
つまり、optionsの中に:prependが入っていれば、before_action_method = :prepend_before_action。それ以外なら:before_action。
before_actionとprepend_before_actionの違いは下記が参考になれば。
*controller_class.send(before_action_method, options.slice(:only, :except, :if, :unless)) do |controller| ~ end
出たー!なんでもありのsend method!!
send methodを実行しているオブジェクト「controller_class」 は、load_and_authorize_resourceを実行したコントローラ(例えばUsers_controller など)になります!
send methodを使うことで、controller_classが実行できるmethod を全て実行できまするー!privateやprotected の意味、、、とも思いますが、rubyは性善説に基づいて作られてる???Matz様は良い人なんだろな、、(勝手な予想)
第一引数のbefore_action_methodは:prepend_before_action または:before_action。実行したいmethodをシンボル(: 付きの文字列。文字列と思いきや、内部では数値なので処理が軽い)で指定します。
第二引数は、第一引数のmethodに渡す引数。
下記の場合、optionsには:only => [:index, :show], :except => [:edit, :create]がhashで入ってる。
load_and_authorize_resource :only => [:index, :show] , :except => [:edit, :create]
options.slice(:only, :except, :if, :unless)で、options内から、:only, :except, :if, :unlessのもののみ取り出す。
なんでdo ~ end文になってるかは分からないけど、:prepend_before_actionまたは:before_actionは実行後にコントローラの名前をarray で返すのかな??
*controller.class.cancan_resource_class.new(controller, resource_name, options.except(:only, :except, :if, :unless)).send(method)
controller.class.cancan_resource_class.newで、initialize が呼ばれて、
@controller = controller (Uses_controllerなど)
@params = controller.params (コントローラのparams. Users_controllerなら例えばname, ageなど)
@options = args.extract_options! (:only => [:index, :show]など)
@name = args.first (:only => [:index, :show]など)
がセットされます
send(method)で、methodには:load_and_authorize_resourceが入っているので、:load_and_authorize_resource が実行されます!
def load_and_authorize_resource
load_resource
authorize_resource
end
今日はここまでー!
次回はload_resourece methodを扱っていきます。
おやすみなさいいいいぃぃぃ