【Ruby on Rails】deviseの導入

Ruby on Railsの便利機能であるdeviseの導入手順をまとめます。

## 環境

|                | Version     |
|:---------------|------------:|
| MacOS Catalina | 10.15.7     |
| Ruby           | 2.6.5       |
| Rails          | 6.0.3.5     |


## Gemfile

Gemfileの一番下に下記を記述します。

```Ruby:Gemfile
gem 'devise'
```

ターミナルで下記コマンドを実行しgemを読み込みさせます。

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

ターミナルで下記コマンドを実行しdeviseを導入します。

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

下記のようなメッセージが出てそれぞれファイルが生成されます。

```
create  config/initializers/devise.rb
create  config/locales/devise.en.yml
```

## モデル作成

Userモデルを作成します。
ターミナルで下記コマンドを実行します。

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

下記のような実行結果がでます。
メッセージにあるように`app/models`に`user.rb`というモデルファイルが生成されます。

```Ruby:ターミナル
Running via Spring preloader in process 1632
      invoke  active_record
      create    db/migrate/2021×××_devise_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml
      insert    app/models/user.rb
       route  devise_for :users
```

## マイグレーションファイル編集

`db/migrate`に新しく`2021×××_devise_create_users.rb`というマイグレーションファイルが生成されているので編集が必要であれば編集します。

例えば、元々はユーザー登録に`email`と`password`しか必要ないようになっているので、下記のように`string型`の`name`を追加したりできます。

```db/migrate/2021×××_devise_create_user.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: ""

     # 下記を追加
      t.string :name,               null: false
```

編集したら下記コマンドでマイグレーションを実行します。

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

## ビュー作成

devise用のビューを作成します。
下記コマンドを実行します。

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

下記のような実行結果が出てdeviseに関する様々なファイルが生成されたことが分かります。

```Ruby:ターミナル
Running via Spring preloader in process 1841
      invoke  Devise::Generators::SharedViewsGenerator
      create    app/views/devise/shared
      create    app/views/devise/shared/_error_messages.html.erb
      create    app/views/devise/shared/_links.html.erb
      invoke  form_for
      create    app/views/devise/confirmations
      create    app/views/devise/confirmations/new.html.erb
      create    app/views/devise/passwords
      create    app/views/devise/passwords/edit.html.erb
      create    app/views/devise/passwords/new.html.erb
      create    app/views/devise/registrations
      create    app/views/devise/registrations/edit.html.erb
      create    app/views/devise/registrations/new.html.erb
      create    app/views/devise/sessions
      create    app/views/devise/sessions/new.html.erb
      create    app/views/devise/unlocks
      create    app/views/devise/unlocks/new.html.erb
      invoke  erb
      create    app/views/devise/mailer
      create    app/views/devise/mailer/confirmation_instructions.html.erb
      create    app/views/devise/mailer/email_changed.html.erb
      create    app/views/devise/mailer/password_change.html.erb
      create    app/views/devise/mailer/reset_password_instructions.html.erb
      create    app/views/devise/mailer/unlock_instructions.html.erb
```

簡易的なビューがこれだけで簡単に生成できてしまいます。


## おまけ

バリデーションはモデルに記述します。
下記が例です。

```Ruby:app/models/user.rb
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  # 下記を追加
  validates :name, presence: true
end
```


カラムにデフォルトの`email`と`password`以外を追加した場合は、それも保存できるように許可の記述をしないと弾かれてしまいます。
`app/controllers/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
```

`before_action :configure_permitted_parameters, if: :devise_controller?`でdeviseに関わる動作については全て起動するように設定します。
そしてその処理として`configure_permitted_parameters`で今回作成した`name`も許可するように記述します。
`configure_permitted_parameters`という名前は慣習的なものらしいので特に意味はありません。


以上です。