tapitapi’s blog

1日1杯タピオカ!エンジニア

【Ruby on Rails: cancancan】canの旅 (ソースコードリーディング)第四回

目指せ!ruby&railsマスター!

 

ということで、cancancanソースコードリーディング第四回はじめます。

 

前回まではコチラ

第一回第二回第三回

 

前回、ability/rules.rb のadd_rule_to_index methodまで確認しました。

 

今回はコントローラに書く「load_and_authorize_resource method」を扱っていきます!

 

controller_additions.rb に「load_and_authorize_resource method」が定義されています。

 

module CanCan
 module ControllerAdditions
  module ClassMethods
   def load_and_authorize_resource(*args)       cancan_resource_class.add_before_action(self,:load_and_authorize_resource, *args)
   end

 

(以下略)

   def cancan_resource_class
    ControllerResource
   end

  end

 end

end

 

if defined? ActiveSupport
 ActiveSupport.on_load(:action_controller) do
  include CanCan::ControllerAdditions
 end
end

 

module ClassMethodsについてはコチラを参考にしました。

(これで、CanCan::ControllerAdditionsモジュールをインクルードしたクラスで、「load_and_authorize_resource」を、クラスメソッドとして使えるようになります)

qiita.com

 

ActiveSupport.on_load(:action_controller)で、ActionController::Base(すべてのコントローラのおばあちゃん)が実行されるときにinclude CanCan::ControllerAdditions が実行されます。

つまり、すべてのコントローラで、ControllerAdditionsのメソッド(load_and_authorize_resourceを含む)を使えるようになる!!

railsguides.jp

 

 

なにこれすごい!!!

めっちゃ便利やん!!!

 

 

「load_and_authorize_resource method」の実態はControllerResource.add_before_action(クラスメソッド)とわかったので、ControllerResourceクラスを見ていきましょう!

 

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

 

require_relative 'controller_resource_loader.rb'

include ControllerResourceLoader でインクルードしているControllerResourceLoaderモジュールはとりあえずスキップ!!

 

*ControllerResource.add_before_actionの引数は(self,:load_and_authorize_resource, *args)

 

まずselfは、ControllerAdditionsモジュールをインクルードしたコントローラになります。たとえばUsers_Controllerなど。

 

:load_and_authorize_resourceは、load_and_authorize_resourceメソッドなので、中身はとりあえずスキップ!

 

*argsは可変長引数で、下記の場合、:only => [:index, :show]が*argsになりますね。

load_and_authorize_resource :only => [:index, :show]

 

今日はControllerResource.add_before_actionの引数まで見ていきました!

 

次回はControllerResource.add_before_actionの内部を扱っていきます。

 

まだまだ旅は長そうです!

 

おやすみなさいいいぃぃぃ