deviseで作成したUserモデルにusernameカラムを追加してDBへ登録できるようにする

## 環境
```
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
Rails 5.1.6
devise 4.4.3
```
「devise」のGitHubは下記
https://github.com/plataformatec/devise

## はじめに
Railsチュートリアルやプログラミングスクールのカリキュラム、そして個人開発をRailsで行う場合、アカウント登録機能の実装手段としてdeviseは鉄板のライブラリです。。しかしdeviseから作成したUserモデルはデフォルトの状態だと、emailとpasswordでしかアカウント情報を登録できません。
※Userモデルにusernameというカラムを追加しフォームに情報を入力しても、DBにはusernameカラムがnilの状態でPUTされる。

個人開発の際、usernameを登録できるようにしたかったため、その手順をメモしておきます。

## deviseをインストールする

Gemfileに下記を追加する。

```ruby:Gemfile
gem 'devise', '4.4.3'
```
4.4.3はgemのバージョンのこと。Gemfileに記載された内容をもとにRailsはGemfile.lockを作成します。Gemfileでgemのバージョンを指定しなければ、後述のbundle install時にRailsは勝手に最新版のgemをインストールしてくれる。しかし意図しない最新版へのアップロードによってライブラリ同士の干渉が起こり、アプリが正常に動作しなくなる可能性もあるためオススメできません。
gemのバージョンを今回のように明示的に指定することで、無用な事故を防ぐことが出来る。

次にターミナルで下記を実行する。bundle updateは不要かも。

```
$ bundle update
$ bundle install
```

ジェネレータを使ってdeviseをインストールする。ターミナルで下記を実行する。

```terminal
$ rails g devise install

Running via Spring preloader in process 30712
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:

       config.assets.initialize_on_precompile = false

     On config/application.rb forcing your application to not access the DB
     or load models when precompiling your assets.

  5. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================

```

これでdeviseのインストールは完了。
## User モデルを作成する
```
$ rails g devise User
invoke  active_record
      create    db/migrate/20190829141850_devise_create_users.rb
      create    app/models/user.rb
      invoke    rspec
      create      spec/models/user_spec.rb
      invoke      factory_bot
      create        spec/factories/users.rb
      insert    app/models/user.rb
       route  devise_for :users
```

次はUserモデルにusernameカラムを追加する。

## usernameカラムを追加する

Userモデルにusernameカラムを追加するためにマイグレーションファイルを作成する。ターミナルで下記を実行する。

```
$ rails g migration add_username_to_users username:string
```

カラムを追加するマイグレーションファイルには命名規則がある。スネークケースで下記のように書く。

```
add_{追加するカラム名}_to_{カラムを追加するモデル名を複数形で}
```
マイグレーションファイルが作成できたらマイグレーションを実行してDBに反映させる。

```
$ rake db:migrate
```

このままだと、usernameカラムは作成できたがDBへPUTしても情報が保存されない。

## usernameを登録できるようにする

strong parameterをapplication_controller.rbに追加する。

```Ruby:application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    added_attrs = [ :email, :username, :password, :password_confirmation ]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
    devise_parameter_sanitizer.permit :sign_in, keys: added_attrs
  end
end
```

このように書くことで、usernameとpasswordでのログインも可能になります。

devise.rbにも下記を追加する。

```Ruby:devise.rb
Devise.setup do |config|
  config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
  require 'devise/orm/active_record'  

  ・・・
  config.scoped_views = true
  ・・・

end
```

これでOKです。

## Viewをカスタマイズしてusernameを入力できるようにする

ターミナルで下記を実行する。

```
$ rails g devise:views
```

Viewにusernameを入力するfieldを追加します。

```erb:views/registrations/new.html.erb
<h2>新規登録</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

  <div class="field">
    <%= f.label :メールアドレス %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email", class: "form-control" %>
  </div>

  <div class="field">
    <%= f.label :ユーザーネーム %><br />
    <%= f.text_field :username, class: "form-control" %>
  </div>

  <div class="field">
    <%= f.label :パスワード %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %>文字以上)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "off", class: "form-control" %>
  </div>

  <div class="field">
    <%= f.label :パスワード再入力 %><br />
    <%= f.password_field :password_confirmation, autocomplete: "off", class: "form-control" %>
  </div>

  <div class="actions">
    <%= f.submit "登録", class: "btn btn-primary btn-block" %>
  </div>
<% end %>

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

これでUserモデルにusernameを登録できるようになりました。