既存のPJにdeviseのconfirmableを実装する(Ruby on Rails)

#Ruby on Rails 既存のPJにdeviseのconfirmableを実装する

- Rails:5.0.2
- ruby:2.4.0
- すでにdeviseが実装されているrailsのPJでdeviseのconfirmableを有効にする。
- PJではユーザーテーブルが既に存在する。confirmable用のカラムは存在しない。
- 上記の状態からconfirmableの機能を利用してユーザーが初回ログインするところまで
- 今回は下記の記事を参考にさせていただきました。
http://qiita.com/cigalecigales/items/f4274088f20832252374

#実装状況の確認
上記の記事を参考に実装状況の確認を行う。

- gem'devise'はインストール済
- rails g devise:installした場合に表示される項目の確認
 
1: default url

```ruby:environments/developments.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```

```ruby:config/routes.rb
root to: 'home#index'
```
→このままにしました。

2: DeiviseのViewファイルの生成
→Devise用のViewファイルは生成されていなかったのでこのタイミングで作成しました。

```
Expected string default value for '--jbuilder'; got true (boolean)
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
```

3:flashメッセージの設定はこのタイミングではスルーしました。
4:Rails3.2用の設定は不要でした。

# 既存のUserテーブルにconfirmable用のカラムを追加する
今回、プロジェクトでは、ridgepoleでのDB管理を行っているのでそれに合った手法でカラム追加を行いました。
http://techlife.cookpad.com/entry/2014/08/28/194147

- カラム追加処理（備忘）

例えば、user tableに1つカラムを追加するときDB（このPJではMySQL）側からカラム追加を行います。

```mysql
ALTER TABLE tbl_name ADD [COLUMN] column_definition;
```
DB側でカラム追加が完了したら、下記のrakeタスクを実行します。

```bundle exec rake ridgepole:export
```
成功するとしたみたいな感じになる。


confirmable用のカラムとして下記を追加。

```
t.string   "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string   "unconfirmed_email"
```


rails sをすると```http://localhost:3000/users/sign_in```でエラー

```
undefined method `new_confirmation_path' for #<#<Class:0x007f108477ee08>:0x007f108c420308>
Did you mean?  new_user_confirmation_path
               user_confirmation_path
```
こちらは、```new_user_confirmation_path```に修正することで画面が正常に表示されました。
修正後の画面は下記のようになりました。

![WS000038.JPG](https://qiita-image-store.s3.amazonaws.com/0/139636/b329a055-62f4-d6d3-5813-81f3d1fdc4b9.jpeg)

# アカウント登録メールを送ってみる

- メールの送信設定


gmailの設定、送信用のメールを設定を行います。
基本的に、参考記事http://qiita.com/cigalecigales/items/73d7bd7ec59a001ccd74 
の通りなのですが、一部違うところがありました。

```ruby:config/initializers/devise.rb
Devise.setup do |config|
 ~省略~
  # ==> Mailer Configuration
  # Configure the e-mail address which will be shown in Devise::Mailer,
  # note that it will be overwritten if you use your own mailer class
  # with default "from" parameter.
  config.mailer_sender = '認証メールの送信元のメールアドレス'
end
```

```ruby:config/environmetns/developments.rb
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  # mail setting
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :enable_starttls_auto => true,
    :address => "smtp.gmail.com",
    :port => 587,
    :domain => 'smtp.gmail.com',
    :user_name => "xxxxxxxx@gmail.com", #gmailアドレス
    :password => "password", #gmailパスワード
    :authentication => 'login',
  }
```

Sign Upすると、エラーになりました。下のログ

```
Started POST "/users" for 127.0.0.1 at 2017-07-15 00:52:53 +0900
Processing by Devise::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Cu1CQIG9vGl2nChHvYoZh3D+uNLgKMVgWuNRDUOGCP5xUFHwOZu/cvcD9lrUHyd1JOAdkjBcGnoJZUT+1VCfpw==", "user"=>{"email"=>"xxxxxxxx@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
  [1m[35m (0.4ms)[0m  [1m[35mBEGIN[0m
  [1m[36mUser Exists (0.8ms)[0m  [1m[34mSELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'youdoumei2@gmail.com' LIMIT 1[0m
  [1m[35m (0.3ms)[0m  [1m[31mROLLBACK[0m
Completed 500 Internal Server Error in 244ms (ActiveRecord: 1.5ms)


  
NameError (undefined local variable or method `confirmed_at' for #<User:0x007f108c896298>
Did you mean?  confirmed?):
```
いくつかエラーメッセージから検索してみたけど、原因がわからず…一旦放置して翌日試してみるとうまくいく。その時のログは下。

```
Started POST "/users" for 127.0.0.1 at 2017-07-16 14:37:38 +0900
Processing by Devise::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"bj+knqhJcxtaKTddaWc75z9JgFiJLWn6qwhgJcolQLsVgrcuEG9wANu26UAA8gUVa1clGFlZtuD4jnXWXPPX4g==", "user"=>{"email"=>"xxxxxxxx@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
  [1m[35m (0.4ms)[0m  [1m[35mBEGIN[0m
  [1m[36mUser Exists (4.9ms)[0m  [1m[34mSELECT  1 AS one FROM `users` WHERE `users`.`email` = BINARY 'youdoumei2@gmail.com' LIMIT 1[0m
  [1m[35mSQL (9.2ms)[0m  [1m[32mINSERT INTO `users` (`email`, `encrypted_password`, `created_at`, `updated_at`, `confirmation_token`, `confirmation_sent_at`) VALUES ('xxxxxxxx@gmail.com', '$2a$11$yiWrcbLuo0tDRfAq6nHZyumDu.d1tHxpRpj3JOufTxFumJKQInqnS', '2017-07-16 05:37:39', '2017-07-16 05:37:39', '2GHvUrpN-z44ENx_prW5', '2017-07-16 05:37:39')[0m
  [1m[35m (11.1ms)[0m  [1m[35mCOMMIT[0m
  Rendering devise/mailer/confirmation_instructions.html.erb
  Rendered devise/mailer/confirmation_instructions.html.erb (1.6ms)
Devise::Mailer#confirmation_instructions: processed outbound mail in 1637.4ms
Sent mail to xxxxxxxx@gmail.com (5299.1ms)
Date: Sun, 16 Jul 2017 14:37:45 +0900
From: xxxxxxxx@gmail.com
Reply-To: xxxxxxxx@gmail.com
To: xxxxxxxx@gmail.com
Message-ID: <596afba99020c_2273ffff15ba57842478@takahirou-PC.mail>
Subject: Confirmation instructions
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<p>Welcome xxxxxxxx@gmail.com!</p>

<p>You can confirm your account email through the link below:</p>

<p><a href="http://localhost:3000/users/confirmation?confirmation_token=2GHvUrpN-z44ENx_prW5">Confirm my account</a></p>
```

これで登録メールを送って認証してログインするところまでの設定が完了しました。
（再起動が必要だったようです→[ソース](https://stackoverflow.com/questions/7613069/undefined-method-new-confirmation-path-confirmation-module-devise-mongoid/12698779)）

今回の記事はここまでです。