deviseでnameとpasswordのみでユーザー登録とログインできるように、初心者がdeviseをカスタマイズ！〜徹底的にゆっくり解説〜

##この記事のissue一覧
* deviseで生成するモデルへのnameカラムの設定のしかた
* ユーザー登録時にpasswordの引数がないと怒られる原因
* パスワードの問題を解決しても生じたDBの問題

##概要
ユーザー登録とログイン（nameとpasswordのみを使用する）をdeviseで生成できるようにしました。


##導入手順

前提　deviseのインストールと、deviseに必要なカラムをもつuserモデル、view/cntrollersの生成までできているとします。

①devise.rbをいじる
②viewにカラムを足す
③controllersにストロングパラメーターを追加する
④動作確認！

注意！　既存プロジェクトに導入の場合、もともとDBにあったユーザーがどうなるのかの検証はまだできてません！悪しからず！当たり前ですが、既存のプロジェクトに適用する場合はブランチ切ってDBのバックアップは取ってから実装お願いします！

##devise.rbをいじる
deviseはデフォルトではemailとpasswordで認証をしているので、emailの部分をnameに変えてあげれば期待した通りの働きをしてくれるはずです。

なのでまずやることはemailがデフォルトではどんな風に使われているのか知ることです。

まあ調べる必要はありません。

```
config/initializers/devise.rb

# ==> Configuration for any authentication mechanism
  # Configure which keys are used when authenticating a user. The default is
  # just :email. You can configure it to use [:username, :subdomain], so for
  # authenticating a user, both parameters are required. Remember that those
  # parameters are used only when authenticating and not when retrieving from
  # session. If you need permissions, you should implement that in a before filter.
  # You can also supply a hash where the value is a boolean determining whether
  # or not authentication should be aborted when the value is not present.
  # config.authentication_keys = [:email]
```

こうかいてあります。
ざっくりいうと、userを認証してる時にデフォルトで使ってるのはemailです。一番下を書き換えることでその設定の上書きができます。

```
config.authentication_keys = [:name]
```
なので、こんな風にハッシュタグを外してシンボルを変えてnameで認証できるようにしましょう。

##viewにカラムを足す

次にやることはviewにnameを送るためのカラムを足します。


```
views/devise/registrations/new
<h2>Sign up</h2>

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

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

  <div class="field">
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br/>
    <%= f.password_field :password, autocomplete: "new-password" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
  </div>

  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>
```

こんな風に、emailの部分をnameに変更してあげましょう。ハッシュタグで記述されている行は変更前です。

##controllersにストロングパラメーターを追加する

さてこれで完成とはなりません。

deviseにはstrong_parametersという考え方があります。

> githubより引用
Strong Parameters

>When you customize your own views, you may end up adding new attributes to forms. Rails 4 moved the parameter sanitization from the model to the controller, causing Devise to handle this concern at the controller as well.

>There are just three actions in Devise that allow any set of parameters to be passed down to the model, therefore requiring sanitization. Their names and default permitted parameters are:

>・sign_in (Devise::SessionsController#create) - Permits only the authentication keys (like email)
・sign_up (Devise::RegistrationsController#create) - Permits authentication keys plus password ・and password_confirmation
・account_update (Devise::RegistrationsController#update) - Permits authentication keys plus password, password_confirmation and current_password

https://github.com/plataformatec/devise#strong-parameters

ざっくりいうと、デフォルトだと:emailなどの決められたparamsしか受け取らねーよって事です。

そのために、自分でparamsを受け取れるように設定する必要があります。

```
/controllers/users/registrations_controller.rb
  before_action :configure_permitted_parameters, if: :devise_controller?

  ~~

  protected

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

こんな風にcontrollersにこいつも追加で受け取れるんだよ〜って明記してあげましょう。

~~まじでクソだるい~~

##動作確認！

これで動くはずです。

##終わりに

英弱ながら頑張って調べたので参考になれば幸いです！

## 参考
https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address
https://github.com/plataformatec/devise/wiki/How-To:-Override-confirmations-so-users-can-pick-their-own-passwords-as-part-of-confirmation-activation
https://stackoverflow.com/questions/12715627/devise-and-rails-argumenterror-in-deviseregistrationscontrollercreate
https://teratail.com/questions/135196
https://github.com/plataformatec/devise#strong-parameters