はじめに
cancancanのソースコードを読んでいたら知らなかった機能(おそらく公式ドキュメントにもなさそう)を見つけたので記事にします。
試した環境
cancancan 3.5.0
できるようになること
(例)
BooksControllerの各アクションに対して、Book
もしくはUser
のどちらかのmanage権限を持っていれば操作ができるようにする
結論
以下のようにany: 配列
のHashの形で書いてあげることで、
UserとBookのどちらか一方にmanage権限がある場合に操作を許可できるようになります。
books_controller
class BooksController < ApplicationController
before_action ->{ authorize! :manage, any: [User, Book] }
# ...略
end
該当のソースコード
controllerでauthorize!
を設定した場合、cancancanのgemの下記のところを通るのですが、ここでsubject(チェック対象のリソース)がany
のkey付きのHashの場合が想定されています。
コードコメントにもsubjectが複数渡されたとき用であることの記載があります・
gems/cancancan-3.5.0/lib/cancan/ability.rb
# It translates to an array the subject or the hash with multiple subjects given to can?.
def extract_subjects(subject)
if subject.is_a?(Hash) && subject.key?(:any)
subject[:any]
else
[subject]
end
end
さいごに
cancancanのソースコードを読んでいたら思わぬ発見があり、面白かったです。