初めてのdevise ② -- カラムを追加してみる -- ～ やってみようカスマイズ！ ～


webアプリの重要機能の一つであるログイン認証管理を簡単に導入するgemです。
カスタマイズも色々できるようで、便利そうだ！でも、調べると使いこなすまで難しそう。。
自分の理解を深めるためにも、何回かに分けてまとめてみることにしました。

1回目はこちら
丁寧版　　　：[初めてのdevise ① -- 導入してみる --]
(http://qiita.com/uloruson/items/ffb3d719b6d2fbea1afd)
コードだけ版：[早くdeviseいれたいねん！ ① -- 入門手順で導入してみる --](http://qiita.com/uloruson/items/e3aceaeab571c4b251ce)


前回はdeviseの最低限の導入ができました。
今回は以下のカスタマイズを行います。

**1. modelにname(名前) age(年代)カラムを追加します。**
**2. viewに追加したカラムを表示させます。**
**3. 追加したカラムをDBへ登録できるようにします。**

## **環境**
- Ruby 2.3.3
- Rails 4.1.16
- Windows 8 64bit
- devise 4.2.0

## **手順**
### **① 独自のカラムを追加**

name age といった２つのカラムを追加します。
```bash
$ rails g migration AddColumnToUsers name age
      invoke  active_record
      create    db/migrate/20170305070915_add_column_to_users.rb
```

作成されたマイグレーションを確認します。
今回はnameだけ少し変更します。（入力必須、デフォルトを空白を入れる設定）

```rb:20170305070915_add_column_to_users.rb
class AddColumnToUsers < ActiveRecord::Migration
  def change
    add_column :users, :name, :string, null: false, default: ""
    add_column :users, :age, :integer
  end
end
```

保存したら、マイグレートしましょう。

```bash
$ rake db:migrate
== 20170305070915 AddColumnToUsers: migrating =================================
-- add_column(:users, :name, :string, {:null=>false, :default=>""})
   -> 0.0050s
-- add_column(:users, :age, :integer)
   -> 0.0003s
== 20170305070915 AddColumnToUsers: migrated (0.0060s) ========================
```

これでFBにカラムが追加されたはず。コンソールで確認しましょう

```bash
$ rails c
Loading development environment (Rails 4.1.16)
$ User.column_names
=> ["id", "email", "encrypted_password", "reset_password_token", "reset_password_sent_at", "remember_created_at", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_i
n_ip", "created_at", "updated_at", "name", "age"]
````

追加されれますね。DBへのカラム追加は完了です。


### **② Viewに独自カラムのフォームを追加**

まずはカスマイズするViewを作成します。
deviseの手引きに従い、下記コマンドを実行します。

```bash
$ rails g devise:views
Expected boolean default value for '--markerb'; got :erb (string)
      invoke  Devise::Generators::SharedViewsGenerator
      create    app/views/devise/shared
      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/password_change.html.erb
      create    app/views/devise/mailer/reset_password_instructions.html.erb
      create    app/views/devise/mailer/unlock_instructions.html.erb
```

次は、sign_up用のviewに追加カラムを入力フォームを追加します。

```erb:devise\app\views\devise\registrations\new.html.erb
<h2>Sign up</h2>

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

<!--  ↓これを追加↓-->

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

  <div class="field">
    <%= f.label :age %><br />
    <%= f.number_field :age %>
  </div>
  
<!--  ↑ここまで↑-->

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email%>
  </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: "off" %>
  </div>

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

  <div class="actions">
    <%= f.submit "Sign up" %>![test.png](https://qiita-image-store.s3.amazonaws.com/0/158572/63b1513b-8ebe-268c-d039-f04162b7eb05.png)

  </div>
<% end %>

<%= render "devise/shared/links" %>
```
ここまでできたら、表示してみましょう。

![test.png](https://qiita-image-store.s3.amazonaws.com/0/158572/7a678211-75b6-6593-5bec-4f5d35f8b5b0.png)

nameとageが追加されていますね。
ボタンを押してもエラーもでませんが、nameとageはDBへ登録されません。

### **③ 追加したカラムをDBへ反映**

いわゆるstrong parameters設定が必要になります。
以下のようにすると、設定できます。

```rb:devise\app\controllers\application_controller.rb
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

# ↓これを追加↓
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

    def configure_permitted_parameters
      devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :age])
    end
# ↑ここまで↑

end
```

これでDBへ反映されます。
Viewをいじって確認してみてください。もちろんコンソールからでも確認できます。