【Rails】ユーザー管理機能(devise)の導入

# 目的
Railsで作成したアプリにユーザー管理機能を導入する。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提
- アプリが作成されている。
- アプリ名は`test-app`とする。

# 手順

1. [そもそもdeviseとは](#そもそもdeviseとは)
1. [Gemのインストール](#gemのインストール)
1. [deviseの設定ファイルを作成](#deviseの設定ファイルを作成)
1. [deviseのUserモデルを作成](#deviseのuserモデルを作成)
1. [テーブルを作成](#テーブルを作成)
1. [deviseのビューファイルを作成](#deviseのビューファイルを作成)
1. [usersテーブルにカラムを追加](#usersテーブルにカラムを追加)
1. [deviseにストロングパラメーターを設定](#deviseにストロングパラメーターを設定)
1. [ユーザー管理リンクの設置](#ユーザー管理リンクの設置)

# そもそもdeviseとは

ユーザー管理機能を実装するためのGemの事です。
deviseを導入することにより、簡単にユーザー管理機能を実装することができます。

# Gemのインストール

それでは早速deviseをインストールしていきましょう！

まずGemfileに下記のようにdeviseを追記します。

```ruby:Gemfile
# 中略
gem 'devise'
```

その後、ターミナルでGemをインストールします。

```:ターミナル
% bundle install
```

インストール後はサーバーを再起動することを忘れずに！
インストールしたGemが反映されるタイミングはサーバー起動時のため、下記コマンドで再起動しましょう！

```:ターミナル
% rails s
```

これでdeviseがインストールできたはずです。

# deviseの設定ファイルを作成

次に設定関連に使用するファイルを生成します。
deviseを使用するためには、 専用のコマンドで設定ファイルを作成する必要があるので注意してください。

```:ターミナル
% rails g devise:install
```

コマンドを実行すれば設定ファイルが作成されるので、次へ進みましょう！

# deviseのUserモデルを作成

deviseを使用する際には、deviseで認証するためのUserモデルを新しく作成する必要があります。
作成にはdeviseのモデル作成用コマンドでUserモデルを作成します!

```:ターミナル
% rails g devise user
```

この際に、ユーザーに関するモデルやマイグレーションも自動生成されています。
また、routes.rbに以下のルーティングが自動的に追記されます。

```ruby:config/routes.rb
Rails.application.routes.draw do
  devise_for :users
end
```

# テーブルを作成

先ほど自動生成されたマイグレーションファイルを使用して、テーブルを作成します。

```ruby:db/migrate/20XXXXXXXXX_devise_create_users.rb
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
 def change
   create_table :users do |t|
     ## Database authenticatable
     t.string :email,              null: false, default: ""
     t.string :encrypted_password, null: false, default: ""

     ## Recoverable
     t.string   :reset_password_token
     t.datetime :reset_password_sent_at

     ## Rememberable
     t.datetime :remember_created_at

     # 省略

     t.timestamps null: false
   end

   add_index :users, :email,                unique: true
   add_index :users, :reset_password_token, unique: true
   # add_index :users, :confirmation_token,   unique: true
   # add_index :users, :unlock_token,         unique: true
 end
end
```

マイグレーションファイルを確認すると、すでにメールアドレスとパスワードのカラムを作成する記述があります。
他のカラムを追加する場合はこのタイミングで追記します。(今回はひとまずこのまま進めます！)

テーブルの設計を確認した後、下記コマンドでマイグレーションを実行しましょう！

```:ターミナル
% rails db:migrate
```

これで、usersテーブルが作成されました!

テーブル・カラム情報を変更したため、サーバーを再起動してください。

```:ターミナル
% rails s
```

これで`http://localhost:3000`へアクセスしても問題なく動作します。

# deviseのビューファイルを作成

deviseでログイン機能を実装すると、ログイン/サインアップ画面が自動的に生成されますがビューファイルとしては生成されません。
これは、deviseのGem内に存在するビューファイルを読み込んでいるためです。
このままではビューファイルを編集できないため、deviseのコマンドを利用して、ビューファイルを生成します。

```:ターミナル
% rails g devise:views
```

このコマンドはdevise内のビューファイルをコピーし、app/viewsの配下に配置してくれるコマンドです。
これでビューファイルの編集が可能になります!

以上で一通りdeviseの導入はできましたが、現状メールアドレスとパスワードのカラムしか存在していません。
ユーザー名など他にも保存したいデータを追加したい場合の方法も合わせて記載します！

# usersテーブルにカラムを追加
まずはテーブルにカラムを追加するために、マイグレーションを生成します!
今回はユーザー名のカラムを追加していきます。

```:ターミナル
% rails g migration AddNameToUsers name:string

% rails db:migrate
```

作成済みのテーブル内容を変更する際には`rails g migration`コマンドを使用します!

このコマンドは、指定するファイルの名前によって、どのようなテーブル操作を行うかを自動で記述してくれます。
`rails g migration Addカラム名To追加先テーブル名 追加するカラム名:型`とすることで、
テーブルに必要なコードが記述された状態で、マイグレーションが生成されます。

サーバーの再起動も忘れずに行いましょう！

```:ターミナル
% rails s
```

これでユーザー名のカラムが追加されました!

# deviseにストロングパラメーターを設定

次にdeviseにストロングパラメーターを設定していきます！
今回は新規登録時の処理に対して、nameというキーのパラメーターを新たに許可します。

ここで注意点ですが、deviseにストロングパラメーターを設定するときは特別な記述が必要です。
それは、deviseの処理を行うコントローラーがGem内に記述されており、編集することができない為です。
そのため、編集可能な`application_controller.rb`にストロングパラメーターを定義しておき、その処理を読み込ませます!

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end
```

`devise_parameter_sanitizerメソッド`を使用し、deviseで設定されているsign_up（新規登録処理）のリクエストからパラメーターを取得しています。

`devise_parameter_sanitizerメソッド`とはdeviseにおけるparamsのようなメソッドです。
このメソッドと`permitメソッド`を組み合わせることにより、新しく追加したカラムもストロングパラメーターに含めることができます!

ちなみに`configure_permitted_parameters`というメソッド名ですが、
deviseの提供元でこのメソッド名を紹介していることから、慣習的に同名で定義することが多いようです!

# ユーザー管理リンクの設置

最後に`新規登録`、`ログイン`、`ログアウト`のリンクを設置します！
条件分岐で、ユーザーがログインしている場合は`ログアウト`を、
ユーザーがログインしていない場合は`新規登録`、`ログイン`を表示しています。

```:.html.erb
<% if user_signed_in? %>
  <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
<% else %>
  <%= link_to "新規登録", new_user_registration_path %>
  <%= link_to "ログイン", new_user_session_path %>
<% end %>
```

これで実装完了です！

# 最後に

長かったですが、以上でユーザー管理機能は導入できたと思います!
あとは各自ビューファイルなど編集してください。
また、`devise`を日本語化したい場合はこちらもどうぞ。[【Rails】Railsの日本語化](https://qiita.com/oak1331/items/563e6ae4786ef61f2687)
では。