【Ruby on Rails: cancancan】canの旅 (ソースコードリーディング)第三回
ということで、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が空配列になるー!
こんな使い方あるんだな、、、知らなかった、、、
使い方参考は下記。(結構昔のリファレンスですが、、、)
*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の無い処理を実行したときに例外発生をしてくれます。
まだまだ旅は長そうです!
おやすみなさいいいぃぃぃ