tapitapi’s blog

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

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

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

 

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

 

前回まではコチラ

第一回第二回

 

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

add_rule_to_index methodの中身を見ていきます!

 

    def add_rule_to_index(rule, position)
     @rules_index ||= Hash.new { |h, k| h[k] = [ ] }

     subjects = rule.subjects.compact
     subjects << :all if subjects.empty?

     subjects.each do |subject|
     @rules_index[subject] << position
    end
   end

引数ruleにはRule.newで生成されたオブジェクトが、

引数positionには前回までに@ruleに入っていた「オブジェクト数」が入っています。

 

*@rules_index ||= Hash.new { |h, k| h[k] = [ ] }

でハッシュが最初に生成されます。Hash.new { |h, k| h[k] = [ ] }でブロックがハッシュに渡される!

 

これ、、どんな使い方???わかんなかったので、調べました!

つまり、@rules_index["a"] が実行されると、@rules_indexの中身は、{"a" => [ ] }となります。つまり、Keyが"a" , valueが空配列になるー!

 

こんな使い方あるんだな、、、知らなかった、、、

 

使い方参考は下記。(結構昔のリファレンスですが、、、)

docs.ruby-lang.org

 

 

*subjects = rule.subjects.compact

can :manage, Shop, user_id: user.idが実行された場合、rule.subjectsは["Shop"] (sizeが1の配列)になります。

compact methodでは、nilが入っていた場合はnilを抜いた配列にしてくれます。

 

つまり、can :manage, Shop, user_id: user.idが実行された場合、subjects = ["Shop"]になっています。

 

*subjects << :all if subjects.empty?

上記で、subjectsが空配列の時は、subjects = [:all] になります。

 

*subjects.each do |subject| ~ end

ここで、配列の中身を一つ一つ処理していきます。

 

処理は

@rules_index[subject] << position

で、@rules_indexというインスタンス変数に引数positionが入っていきます。

 

can :manage, Shop, user_id: user.idが実行された場合、subjects = ["Shop"], position = 0(これが最初に実行されたcan methodの場合)になるので 

 

subjects.each do |subject|
    @rules_index[subject] << position
end 

上記終了すると、@rules_indexの中身は{ "Shop" => [0] }となります。

 

can :manage, Shop, user_id: user.id

can :manage, Shop1, user_id: user.id

can :manage, Shop2, user_id: user.id

の場合は、@rules_indexの中身は{ "Shop" => [0] , "Shop1" => [1], "Shop1" => [2] }となりますね!

 

can methodが終わったーーーー!!!

 

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

 

このload_and_authorize_resource methodがコントローラで毎回実行されることで、

can methodで設定したability(権限)を確認&

ユーザがabilityの無い処理を実行したときに例外発生をしてくれます。

 

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

 

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