【Rails】この記事を「devise 名前 ログイン」で調べたあなたへ贈る

この記事を「devise 名前 ログイン」で調べたあなたへ贈る

## はじめに
[yuki](https://twitter.com/yuki82511988)と申します。DMMWEBCAMPにお世話になって、今はWEBエンジニアをしつつ、自分で仲間を集めてサービス開発したり、プログラミングの家庭教師したり毎日エンジニアライフをエンジョイしています。

きっとあなたは「devise 名前 ログイン」で**Railsのgem、Deviseをを用いて名前とパスワードを使ってログインする方法**を調べに来てくれたんだと思います。

そんなあなたのために、今日はできるだけ関連記事の中で一番わかりやすく、そしてあなたにとってプラスになるように「なぜそれをやるのか」という部分まで解説します。

よければ最後まで頑張ってご覧ください。

なぜなら、あなたは過去の私なのだから・・・

## 記事の対象者
- deviseを使ってログインする方法が知りたい方
- Railsの環境構築は終わっており、deviseでmailとpasswordでのログイン実装をした経験がある方

## 修正方法
それでは、早速方法と理由について述べます。
順番通りに、かつ見落としがないように気をつけてください。
また、名前とパスワードでログインすることを以下「名前ログイン」と呼びます。

### Deviseをインストールして、初期設定をする
まずは、大前提としてdeviseの設定をしていきましょう。

#### Gemfileにdeviseを追記し、インストールする
:white_check_mark: Gemfileの一番下に以下の記述をして

```Gemfile
gem 'devise'
```

:white_check_mark:`bundle install`を実行してください。
これでプロジェクトの中でdeviseを扱えるようになりました。

#### deviseの初期設定
`bundle install`が終わったのちに、deviseをセットアップしていきます。

:white_check_mark:コマンドライン（ターミナルなどコマンドを実行する場所）で`rails g devise:install`を実行してください。

この初期設定は**デバイスの設定をするファイル**を作るために必要です。
これを作っておけば、後で名前ログインするために必要な設定をできるようになります。

#### ログインするために必要なUserテーブルを作成する

次に、そもそも名前ログインに必要なユーザーのデータを保存するテーブルを作成します。

:white_check_mark:コマンドラインで`rails g devise User`を実行してください。

これは、`rails g model User`とはちょっと違っていて、deviseの機能を通じてUserのモデルやらマイグレーションファイルやらを作ってくれます。
なぜそんなことをするかというと、必要なカラム（emailなどの情報を入れる場所）を自動的に作ってくれるからです。

#### Userのモデルを作るマイグレーションファイルに、nameカラムを追加する
先程のコマンドを実行すると、db/migrate/のなかに、マイグレーションファイルができていると思います。`rails db:migrate`を行えばdeviseの機能でログインする際に最低限必要なUserテーブルができるのですが、今回は「名前ログイン」をできるようにしたいので、nameカラムを追加していきます。
理由は単純で、ユーザーの名前を入れておく場所が初期設定のままだと存在していないからです。

こんな感じで追記してあげてください。
※ファイル名は若干各々で作成日時によって変わります。

```db/migrate/2020......devise_create_users.rb
# 中略
      ## Lockable
      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at

      t.string :name # ここに追加したよ！！！！！！！
      t.timestamps null: false
# 中略
```

:white_check_mark:上のコードを追記して`rails db:migrate`を実行

これでnameカラムを持つUserテーブルが作成できました。

### 新規登録の際に、名前を登録できるように必要なviewファイルを可視化させる
これで保存する準備はできたので、新規登録画面でnameの情報を送れるようにしていきます。
しかし、今の状態だと**deviseの新規登録やログインに使う画面を編集することができません**。なぜなら、ファイルが見えないからです。

実際に編集できるようにするために
:white_check_mark:下記のコマンドをコマンドラインで実行しましょう。

`rails g devise:views`

これで、app/views以下にdeviseのフォルダ一式が作成され、deviseの新規登録やログイン画面を書き換えられるようになりました。

肝心のファイルはどれかといいますと、

- 登録はregistrationsの中のnew.html.erb
- ログインはsessionsの中のnew.html.erb

です。

#### 新規登録の画面に、nameを送るフォームを追加する

現在、新規登録の画面からはemailしか送れない状態になっています。

:white_check_mark:これをちょこっと編集して、名前の情報を送れるようにしましょう。

```app/views/users/registrations/new.html.erb
<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "users/shared/error_messages", resource: resource %>

<!-- ここから追加 --!>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
  </div>
<!-- ここまで追加 --!>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>

  <--! これより下は省略 !-->
```
ここまでできたら

:white_check_mark:`rails s`を実行して、`localhost:3000/users/sign_up`にアクセスしてください。名前のフォームもできていたらOKです。

ただし・・・

#### 新規登録の際に、nameの情報を送って良いように許可する
上の手順を行った際に、多分新規登録には成功してRailsの初期画面が現れますが、コマンドラインにこのような不穏な文字が出ているはずです。

`Unpermittted parameter: :name`

これは:nameという値が送信を許可されていないよ。という意味です。
この記事を読んでいる人はきっと「ストロングパラメーター」という言葉を聞いたことがあると思いますが、まさにそれです。

標準では、:nameの値を送ることが許可されていないので、これを許可してあげましょう。

#### ログインに使う値をemailからnameに変更する
上の章で弾かれる要因を直すには、deviseの設定をしているファイルを見に行く必要があります。

思い出してください。`rails g devise:install`した時に作ったファイルですね。

:white_check_mark:では、config/initializers/devise.rbを開いてください。

VSCcodeを使っている方は、cmd(ctrl) + pを押すとファイル名で検索できますよ。

ウジャウジャといろんな設定が書いてあるファイルが開きますが、大丈夫です。
`cmd + f`で文字列を検索できるのですが、config.auまで入力してみてください。

`# config.authentication_keys = [:email]`という記述が見つかるはずです。
deviseはここで、オーセンティケーションに使う鍵（つまりは認証ですね、ログインに使う値だと思ってください）を設定しているので、ここのコメントアウトを外して、emailをnameに変えてあげましょう。

`config.authentication_keys = [:name]`ということですね。

これで`name`を使って認証をすることができます。
ただ、そのせいで**今度は逆にemailの値を送ることができなくなってしまう**ので、修正をしていきましょう。

## emailの値も認証に使えるようにする

:white_check_mark: では、app/controllers/application_controller.rbを編集します。以下のように追記してください。

```app/controllers/application_controller.rb
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:[:email]) # 注目
    end
end
```

こちらのファイルは、アプリケーション全体に関わるコントローラーだと思っていただいて大丈夫です。
ここに書いたものがアプリケーションの処理を実行する際に適用されます。

`before_action :configure_permitted_parameters, if: :devise_controller? `は、わかりやすくいいますと、「もし、deviseの処理を行う場合、`configure_permitted_parameters`というものを実行してね」という意味です。

じゃあ`configure_permitted_parameters`とは何かというと、その下に定義されているメソッドです。`devise_parameter_sanitizer.permit(:sign_up,keys:[:email])`というやつですね。

この箇所はdeviseを使用する際のストロングパラメータを追加する役割を担っています。

deviseではデフォルトでauthentication_keys(初期値はemailのみ)とpasswordがストロングパラメータとなっているので、大抵の場合はapplication_controller.rbにnameをストロングパラメータに追加するコード(修正後のコード)を記述します。
ただ今回は、deviseの設定ファイルも知ってもらいたいため、devise.rbを編集しました。

以下の部分ですね。

```devise.rb
# config.authentication_keys = [:email]
```
↓

```devise.rb
config.authentication_keys = [:name]
```

これによってdevise側で追加されるストロングパラメータがnameとpasswordになるので、application_controller.rbではemailを追加する必要があります。
そのため、ここで再度emailと書いている訳ですね。

:white_check_mark:以上を設定できたら、もう一度新規登録を行ってみましょう。
もう、コマンドラインにさっきのエラーメッセージは出ていないはずです。

ログアウトできねえよ！って方は、cookieを削除するとできます。
MACの場合、URLの横の「i」ボタンを押してみてください。


#### ログインの画面の、emailを送るフォームを、nameを送るフォームに変更する

:white_check_mark:新規登録の画面からnameを登録できるようになったので、当然ログイン画面も修正していきましょう。

```app/views/users/sessions/new.html.erb
<h2>Log in</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "users/shared/error_messages", resource: resource %>

<!-- ここから追加 --!>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name, autofocus: true, autocomplete: "name" %>
  </div>
<!-- ここまで追加 --!>

<!-- ここから削除 --!>
  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>
<!-- ここまで削除 --!>

  <--! これより下は省略 !-->
```
emailに関するフォームを削除して、nameのフォームを追加しました。

:white_check_mark:では、これで先程登録した名前とパスワードでログインしてみましょう。

きっと、エラーが出ずに成功できると思います。

### まとめ
- deviseのインストールと設定をしっかりしよう
- userのマイグレーションファイルにnameカラムを追加しよう
- 新規登録時nameの値が送れるように許可しよう
- ログイン時nameを使ってログイン（正式には認証してもらえるように）できるようにdeviseを設定しよう

といった感じです。

これからも勉強する際は、ぜひ「なんでその記述を書くと思い通りに動くのか」突き詰めて考えてみてください。

応援しています。何か困ったことがあれば、[DM](https://twitter.com/yuki82511988)待っています〜。

#### こんな記事も書いてますという紹介
[【卒業生】DMMWEBCAMPに通おうと思っている人に伝えたいこと](https://qiita.com/yuki82511988/items/37be28f2486e166fd48f)

### 会社の紹介
私は現在、[株式会社ダイアログ](https://www.dialog-inc.com/)という物流×ITの会社に勤務しております。
2020年9月現在、エンジニアの募集はしていませんが、他にも様々な職種を募集しているので、[Wantedly](https://www.wantedly.com/companies/company_3244501)のページをご覧ください。いつか自分のQiitaきっかけで応募してくださる方がいたら、嬉しいなと思います。

[インタビュー記事（入社後の感想など）](https://www.wantedly.com/companies/company_3244501/post_articles/278203)