【学習】deviseの理解向上（遷移について）

## はじめに
今回は下記アドベントカレンダー企画に参加する為、開発でチャレンジした機能についてまとめたいと思います。

https://qiita.com/advent-calendar/2024/engineering-careers-1


## 概要・環境
- Windows, WSL
Docker
Ruby 3.2.3
Rails 7.1.3


以前はユーザー認証で`sorcery`を使用していました。今回はプログラミングスクール内でも次に利用している人が多かった`devise`について触れてみたいと思い早速チャレンジです！！

遷移先について、後で見返せるようにしたいと思い、今回記事にしておきたいと思います。


## 遷移がよくわからなくなった
`sorcery`の感覚で`routes.rb`にルーティングを記載するものかと思っていましたが違った…。この時点で頭の中は「？」がいっぱい。

まずはユーザーのルーティングを確認
```ruby
rails routes -g user


                  Prefix Verb   URI Pattern                    Controller#Action
        new_user_session GET    /users/sign_in(.:format)       devise/sessions#new
            user_session POST   /users/sign_in(.:format)       devise/sessions#create
    destroy_user_session DELETE /users/sign_out(.:format)      devise/sessions#destroy
       new_user_password GET    /users/password/new(.:format)  devise/passwords#new
      edit_user_password GET    /users/password/edit(.:format) devise/passwords#edit
           user_password PATCH  /users/password(.:format)      devise/passwords#update
                         PUT    /users/password(.:format)      devise/passwords#update
                         POST   /users/password(.:format)      devise/passwords#create
cancel_user_registration GET    /users/cancel(.:format)        devise/registrations#cancel
   new_user_registration GET    /users/sign_up(.:format)       devise/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise/registrations#edit
       user_registration PATCH  /users(.:format)               devise/registrations#update
                         PUT    /users(.:format)               devise/registrations#update
                         DELETE /users(.:format)               devise/registrations#destroy
                         POST   /users(.:format)               devise/registrations#create
```

例えば以下のようなコードを書いたとします
```ruby
<%= link_to "ログイン", new_user_session_path %>
```
`rails routes -g user`の結果からわかるように、`new_user_session_path`を使うと、自動的に`/users/sign_in`というURLに遷移することになります。

そして、`devise/sessions#new`アクションが呼ばれます。（このアクションは、ログインページを表示するものです。）


## Devise特有のものだった
- `new_user_session_path`のようなヘルパーは、Deviseが提供するもの。
- Deviseはユーザー認証の機能を簡単に提供するため、セッション、パスワード、登録などのURLやアクションを自動的にセットアップしている。
- これらはDeviseが特有に生成しているため、Deviseを使う場合は**ルーティングを手動で設定する必要がない**


## Deiviseを使用しない場合のルーティングについて
Deviseを使わない場合は、`config/routes.rb`で手動でルーティングを設定することとなります。
たとえば、ユーザーのログイン、ログアウト、サインアップなどのルートを次のように定義することになります（ここがsorceryと違う所？）
```ruby
Rails.application.routes.draw do
  get '/login', to: 'sessions#new', as: 'login'
  post '/login', to: 'sessions#create'
  delete '/logout', to: 'sessions#destroy'

  get '/signup', to: 'users#new', as: 'signup'
  post '/users', to: 'users#create'
end


# 対応するリンクは次のような感じ
<%= link_to "ログイン", login_path %>
<%= link_to "サインアップ", signup_path %>
```


## ここまで確認して疑問に思ったこと
**devise/sessions#newという記述は、sessionsコントローラのnewアクションを指す**

この部分を見た時に私は疑問に思いました
`app/controllers/users/sessions_controller.rb`は以下のようになっていたから。つまり**newアクション定義してないけど？どこ？？**
```
# frozen_string_literal: true

class Users::SessionsController < Devise::SessionsController
  # before_action :configure_sign_in_params, only: [:create]

  # GET /resource/sign_in
  # def new
  #   super
  # end

  # POST /resource/sign_in
  # def create
  #   super
  # end

  # DELETE /resource/sign_out
  # def destroy
  #   super
  # end

  # protected

  # If you have extra params to permit, append them to the sanitizer.
  # def configure_sign_in_params
  #   devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
  # end
end
```

### Deviseの内部処理のおかげらしい
newアクションが`Users::SessionsController`内に記述されていないのに、`app/views/devise/sessions/new.html.erb`が表示されている理由は、Deviseが既に提供する**デフォルトのコントローラアクションとビューを使用している**からになるのだそうで。

最初の一文をよく見てみると、`Users::SessionsController`は、`Devise::SessionsController`を継承しています。つまり、`Devise::SessionsController`に含まれるデフォルトのアクション（new、create、destroyなど）が自動的に利用されているということ！

カスタマイズしたい場合のみ、`Users::SessionsController`でnewアクションを定義すればOK!

Devise::SessionsControllerの中にはすでにnewアクションが定義されていて、ログインフォームを表示する役割を持っています。



## さいごにまとめ+参考記事
使用するGemによって少しコードの書き方も変わってくるので日々勉強。
便利になったときいていても実際に自ら触ってみないとわからないもの。
今回の記事が何か参考になれば幸いです


https://www.sejuku.net/blog/13378#index_id4