Deviseのサインイン後のリダイレクト先は5パターン

# 結論
以下、5パターン。上から順に優先度が高い。

usersというモデルにdeviseをマッピングさせた場合、

- ログイン前にアクセスしようとしたページ
- user_root_path(as: user_root_pathを指定したパターン)
- user_root_path(名前空間 + rootで設定したパターン)
- root_path(deviseマッピングとは関係ないroot_path)
- "/"

# 詳細(サインインの観点から)
「サインイン後のリダイレクト先を設定したい！！」
となると、after_sign_in_path_forメソッドを使いますが、
きちんと理解しておかないと、「なんかうまくいかないな」という状態になりがちです。
しっかりやっていきましょう。

下記は、after_sign_in_path_forのソースです。
[Git_Hub：after_sign_in_path_forメソッド](https://github.com/plataformatec/devise/blob/40f02ae69baf7e9b0449aaab2aba0d0e166f77a3/lib/devise/controllers/helpers.rb)

```devise/lib/devise/controllers/helpers.rb
def after_sign_in_path_for(resource_or_scope)
  stored_location_for(resource_or_scope) || signed_in_root_path(resource_or_scope)
end
```

さすが有名gemです。メソッド名でなんとなくわかりますね！！
- stored_location_for(resource_or_scope)
　未ログイン時にアクセスしようとしたページがあった場合、サインインした後に飛ばす。

- signed_in_root_path(resource_or_scope)
  いきなりログインページにアクセスした場合は、このメソッドの戻り値の場所に飛ばす。

ログイン後のリダイレクト先の理解には、
**signed_in_root_path(resource_or_scope)**メソッド
の理解がキーになりそうです。

早速見てみましょう。

```devise/lib/devise/controllers/helpers.rb
def signed_in_root_path(resource_or_scope)
 # モデルオブジェクトが渡されると、deviseでマッピングされたスコープ(usersとか)を返す。
 # もしdeviseでマッピングしているモデルがadminという名前空間に属している場合、:admin_usersになる。
 scope = Devise::Mapping.find_scope!(resource_or_scope)

 # deviseを使うモデルが複数ある場合、mappings(ハッシュ)のうち[scope]を取得し、そのrouter_nameを代入する。
 # router_nameは、Devise::Mappingに対してoptionが渡されないとnilになるから基本nilっぽい。
 router_name = Devise.mappings[scope].router_name
 home_path = "#{scope}_root_path"

 # router_nameは基本nilっぽいので、実行されない。selfはobjectクラスのmain。
 context = router_name ? send(router_name) : self

 # contextに対してhome_pathを呼べるなら実行。trueはhome_pathがプライベートメソッドでも呼ぶよの意味。
 if context.respond_to?(home_path, true)
  context.send(home_path)
 # contextに対して、root_pathを呼べるなら実行。
 elsif context.respond_to?(:root_path)
  context.root_path
 # ただのroot_pathが呼べるなら実行。
 elsif respond_to?(:root_path)
  root_path
 # トップページにリダイレクト
 else
  "/"
 end
end
```

ふむふむ。
- context.respond_to?(home_path, true)
- context.respond_to?(:root_path)
の違いだけちょっとあいまいだが、

- admin/users#indexとかの名前空間(admin)があるパターンは、
context.respond_to?(home_path, true)で実行される

- 名前空間(admin)がないパターン(usersのみ)は
context.respond_to?(:root_path)で実行される

と理解した。

 ```home_path = "#{scope}_root_path"```の#{scope}は、
**adminとかの名前空間 + deviseでマッピングしているモデル名となる。**

最終的にuser_root_pathとなるのは同じだが、内部的には意味が違うのではないだろうか。。。

下記は、user_root_pathで、home_pathと合致する。
devieでマッピングされたモデルに対して、home_pathはあるか?と聞いている。
```context.respond_to?(home_path, true)```

```ruby
get to: "users#index", as: user_root_path
```

下記は、user_root_pathだが、home_pathとは合致しない。
deviseでマッピングされたモデルに対して、root_pathはあるか?と聞いている。
```context.respond_to?(:root_path)```

```ruby
namespace users do
 root to: "users#index"
end 
```

認識違いあれば、ご指摘ください！！


# 参考URL
- [find_scope!の役割](https://www.rubydoc.info/github/plataformatec/devise/Devise%2FMapping.find_scope!)
- [mappingsのソース](https://github.com/plataformatec/devise/blob/b52e642c0131f7b0d9f2dd24d8607a186f18223e/lib/devise.rb)

- [router_nameのソース](
https://github.com/plataformatec/devise/blob/715192a7709a4c02127afb067e66230061b82cf2/lib/devise/mapping.rb)
[router_nameの役割](https://rubydoc.info/github/plataformatec/devise/master/Devise%2FMapping:router_name)

- [option引数について](
https://techracho.bpsinc.jp/hachi8833/2017_03_22/37313)

- [respond_to?について](https://ref.xaio.jp/ruby/classes/object/respond_to)