devise_for
Deviseを使うとき、 routes.rbに書く devise_for
が何をやっているか。
devse_for?
devise/rails/routes.rb の devise_for
のコメント欄のところ
# Includes devise_for method for routes. This method is responsible to # generate all needed routes for devise, based on what modules you have # defined in your model.
モデル上でDeviseのモジュール設定をベースとして、routesの設定をする。
また、
devise/mapping.rb の先頭のコメント。
# Responsible for handling devise mappings and routes configuration. Each # resource configured by devise_for in routes is actually creating a mapping # object. You can refer to devise_for in routes for usage options.
devise_for の定義は、実質はDevise::Mapping のインスタンスを作成している。
mappingオブジェクト作った後に、 devise_scope を呼び出して、 devise_#{module name}
を呼び出すことで、routesを定義している。
# devise_for メソッドの最下部で、devise_scope を呼び出している箇所。 devise_scope mapping.name do with_devise_exclusive_scope mapping.fullpath, mapping.name, options do routes.each { |mod| send("devise_#{mod}", mapping, mapping.controllers) } end end
例えば、passwordモジュールのroutesは下記のように定義されてる
def devise_password(mapping, controllers) #:nodoc: resource :password, only: [:new, :create, :edit, :update], path: mapping.path_names[:password], controller: controllers[:passwords] end
mappingオブジェクトの設定を元に resource の設定をしてる。
devise_scope?
devise_scope :resource_name &block
で、ブロックにroutesを定義する処理を指定できる。
devise_for でモジュール毎の基本的な設定と各種オプションでの調整はできる。
devise_scope はもっと自由にroutesをカスタマイズするときに使うとのこと。
constraints (配下のネストされたルートに制約をかける処理)で request.env["devise.mapping"] に Devise.mappings[scope]を設定して、
scope :resource_name に、上記で定義したroute情報を渡している
constraints の処理は、initializeのときではなく、実際に対象のrouteにアクセスがあったときに走るので、
deviseのroutesのリクエスト毎に request.env["devise.mapping"] にMapping情報を設定している(目的は謎。)
=以下2020/11/20に追記=
mapping情報はdeviseが複数のresource(UserやAdminのような)に対応するために必要なものだった。 mappingにはuserのようなresource名の情報と、registerableのような設定されているモジュールの情報が格納されている。
DeviseController自体はresourceごとに生成されないので、1つしかない。 なので、mapping情報がないと、今アクセスされている対象のresourceが、例えばuserなのか、adminなのか解らない。
devise.mappingはDeviseControllerに対して、対象のresourceやmoduleの設定を知らせるためのメタ的な情報だった。
まとめ
Railsのroutes周りの仕組みをハックして、deviseの各モジュールで必要なroutesの設定を、簡単で、柔軟な形で行えるようにしているイメージ。