はじめに
cancancanというgemでは、authorize_resource
というメソッドが用意されています。
authorize_resource
は、以下のように使うと、Controller名から対象のリソースを特定してくれる機能があります。
その特定の仕組みが気になったので、今回はそのコードを対象に読んでみました。
class BooksController < ApplicationController
authorize_resource # この場合、Bookに対する権限をチェックしてくれます。
# ...略
end
コードリーディング
authorize_resource
メソッドは以下に定義されていました。
@controller.authorize!
で以前も記事にしたauthorize!
メソッドが使われています。
今回はcontrollerから第二引数のresource_class_with_parent
のソースコードを追っていこうと思います。
def authorize_resource
return if skip?(:authorize)
@controller.authorize!(authorization_action, resource_instance || resource_class_with_parent)
end
parent_resource
はthrough
を使った際に関連しますが、今回は省略します。
resource_class
の定義を見ていきます。
def resource_class_with_parent
parent_resource ? { parent_resource => resource_class } : resource_class
end
@option
には、load_resource
に渡しているオプションの情報が格納されています。
今回はオプションを渡していないので、when nil
に進み、namespaced_name
を返します。
def resource_class
case @options[:class]
when false
# ...略
when nil
namespaced_name.to_s.camelize.constantize
when # ...略
else
# ...略
end
end
namespaced_name
ではnamespace
とname
が使われています。
namespace
とname
によって名前空間も含め、コントローラからリソースとなるモデルを特定していました。
def name_from_controller
@params[:controller].split('/').last.singularize
end
def namespaced_name
[namespace, name].join('/').singularize.camelize.safe_constantize || name
end
def name
@name || name_from_controller
end
def namespace
@params[:controller].split('/')[0..-2]
end
さいごに
authorized_resource
でどうやってリソースを特定しているんだろうと思いましたが、調べてみたらRailsの仕組みをかなり活用していることがわかっておもしろかったです。