35歳だけどRailsチュートリアルやってみた。[第4版 12章 12.4 本番環境でのメール送信 (再掲) まとめ&解答例]

#はじめに
最近、プロジェクト管理業務が業務の大半を占めており、
プログラムを書く機会がなかなかありません。

このままだとプログラムがまったく書けない人になってしまう危機感（迫り来る35歳定年説）と、
新しいことに挑戦したいという思いから、
[Ruby on Rails チュートリアル実例を使ってRailsを学ぼう 第4版](https://railstutorial.jp/)を学習中です。
業務で使うのはもっぱらJavaなのですが、Rails楽しいですね。


これまでEvernoteに記録していましたが、ソースコードの貼付けに限界を感じたため、
Qiitaで自分が学習した結果をアウトプットしていきます。

個人の解答例なので、誤りがあればご指摘ください。

##動作環境
- cloud9
- ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
- Rails 5.0.0.1

##12.4 本番環境でのメール送信
###本章での学び
SendGridとHerokuを使った環境設定なので省略。
詳細は以下参照。

[35歳だけどRailsチュートリアルやってみた。[第4版 11章 11.4 本番環境でのメール送信 まとめ&解答例]](http://qiita.com/yokoyan/items/6dfedd668b03f58d6279)

###本番環境へのデプロイ
####gitへのpush

```irb
yokoyan:~/workspace/sample_app (master) $ git push
Warning: Permanently added 'bitbucket.org,104.192.143.2' (RSA) to the list of known hosts.
Counting objects: 38, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (36/36), done.
Writing objects: 100% (38/38), 5.81 KiB | 0 bytes/s, done.
Total 38 (delta 22), reused 0 (delta 0)
To bitbucket.org:yokoyan/sample_app.git
   81be683..583552c  master -> master
```

####本番環境へのデプロイ

```irb
yokoyan:~/workspace/sample_app (master) $ git push heroku
Counting objects: 38, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (36/36), done.
Writing objects: 100% (38/38), 5.81 KiB | 0 bytes/s, done.
Total 38 (delta 22), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.2.6
remote: -----> Installing dependencies using bundler 1.15.1
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        Fetching gem metadata from https://rubygems.org/.........
remote:        Fetching version metadata from https://rubygems.org/..
remote:        Fetching dependency metadata from https://rubygems.org/.
remote:        Using rake 12.0.0
remote:        Using concurrent-ruby 1.0.5
remote:        Using i18n 0.8.1
remote:        Using minitest 5.10.1
remote:        Using thread_safe 0.3.6
remote:        Using builder 3.2.3
remote:        Using erubis 2.7.0
remote:        Using mini_portile2 2.1.0
remote:        Using rack 2.0.1
remote:        Using nio4r 1.2.1
remote:        Using websocket-extensions 0.1.2
remote:        Using mime-types-data 3.2016.0521
remote:        Using arel 7.1.4
remote:        Using method_source 0.8.2
remote:        Using thor 0.19.4
remote:        Using bundler 1.15.1
remote:        Using bcrypt 3.1.11
remote:        Using will_paginate 3.1.0
remote:        Using execjs 2.7.0
remote:        Using sass 3.4.23
remote:        Using puma 3.4.0
remote:        Using tilt 2.0.6
remote:        Using coffee-script-source 1.12.2
remote:        Using turbolinks-source 5.0.0
remote:        Using multi_json 1.12.1
remote:        Using pg 0.18.4
remote:        Using faker 1.6.6
remote:        Using tzinfo 1.2.2
remote:        Using nokogiri 1.7.0.1
remote:        Using rack-test 0.6.3
remote:        Using websocket-driver 0.6.5
remote:        Using mime-types 3.1
remote:        Using sprockets 3.7.1
remote:        Using bootstrap-will_paginate 0.0.10
remote:        Using autoprefixer-rails 6.7.7.1
remote:        Using uglifier 3.0.0
remote:        Using turbolinks 5.0.1
remote:        Using coffee-script 2.4.1
remote:        Using activesupport 5.0.0.1
remote:        Using loofah 2.0.3
remote:        Using mail 2.6.4
remote:        Using bootstrap-sass 3.3.6
remote:        Using rails-dom-testing 2.0.2
remote:        Using globalid 0.3.7
remote:        Using activemodel 5.0.0.1
remote:        Using jbuilder 2.4.1
remote:        Using rails-html-sanitizer 1.0.3
remote:        Using activejob 5.0.0.1
remote:        Using activerecord 5.0.0.1
remote:        Using actionview 5.0.0.1
remote:        Using actionpack 5.0.0.1
remote:        Using actioncable 5.0.0.1
remote:        Using actionmailer 5.0.0.1
remote:        Using railties 5.0.0.1
remote:        Using sprockets-rails 3.2.0
remote:        Using sass-rails 5.0.6
remote:        Using coffee-rails 4.2.1
remote:        Using jquery-rails 4.1.1
remote:        Using rails 5.0.0.1
remote:        Bundle complete! 25 Gemfile dependencies, 59 gems now installed.
remote:        Gems in the groups development and test were not installed.
remote:        Bundled gems are installed into ./vendor/bundle.
remote:        The latest bundler is 1.15.2, but you are currently running 1.15.1.
remote:        To update, run `gem install bundler`
remote:        Bundle completed (2.63s)
remote:        Cleaning up the bundler cache.
remote:        The latest bundler is 1.15.2, but you are currently running 1.15.1.
remote:        To update, run `gem install bundler`
remote: -----> Installing node-v6.11.1-linux-x64
remote: -----> Detecting rake tasks
remote: -----> Preparing app for Rails asset pipeline
remote:        Running: rake assets:precompile
remote:        I, [2017-07-17T21:27:17.657710 #426]  INFO -- : Writing /tmp/build_2f8a6517b5621aeee4ac52fb92d612f3/public/assets/application-89e6500f2055e9eab169c030a3561a92813a5ce017b6e67ab0df3311b0430f3a.js
remote:        I, [2017-07-17T21:27:17.658277 #426]  INFO -- : Writing /tmp/build_2f8a6517b5621aeee4ac52fb92d612f3/public/assets/application-89e6500f2055e9eab169c030a3561a92813a5ce017b6e67ab0df3311b0430f3a.js.gz
remote:        Asset precompilation completed (9.36s)
remote:        Cleaning assets
remote:        Running: rake assets:clean
remote:        I, [2017-07-17T21:27:22.642501 #445]  INFO -- : Removed application-df52b44ba712a102868f0a043f9a078ac6718902bb3bbd1343d89fed6d71ea09.js
remote: 
remote: ###### WARNING:
remote:        You have not declared a Ruby version in your Gemfile.
remote:        To set your Ruby version add this line to your Gemfile:
remote:        ruby '2.2.6'
remote:        # See https://devcenter.heroku.com/articles/ruby-versions for more information.
remote: 
remote: -----> Discovering process types
remote:        Procfile declares types     -> web
remote:        Default types for buildpack -> console, rake, worker
remote: 
remote: -----> Compressing...
remote:        Done: 38.3M
remote: -----> Launching...
remote:        Released v17
remote:        https://enigmatic-everglades-70434.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/enigmatic-everglades-70434.git
   81be683..583552c  master -> master
```

####本番DBのマイグレーション

```irb
yokoyan:~/workspace/sample_app (master) $ heroku run rails db:migrate
 ▸    heroku-cli: This CLI is deprecated. Please reinstall from https://cli.heroku.com
Running rails db:migrate on ⬢ enigmatic-everglades-70434... up, run.8511 (Free)
D, [2017-07-17T21:28:47.717023 #4] DEBUG -- :    (1.1ms)  SELECT pg_try_advisory_lock(414146247089748600);
D, [2017-07-17T21:28:47.729908 #4] DEBUG -- :   ActiveRecord::SchemaMigration Load (4.8ms)  SELECT "schema_migrations".* FROM "schema_migrations"
I, [2017-07-17T21:28:47.750804 #4]  INFO -- : Migrating to AddResetToUsers (20170703042006)
D, [2017-07-17T21:28:47.755178 #4] DEBUG -- :    (3.2ms)  BEGIN
== 20170703042006 AddResetToUsers: migrating ==================================
-- add_column(:users, :reset_digest, :string)
D, [2017-07-17T21:28:47.762588 #4] DEBUG -- :    (7.0ms)  ALTER TABLE "users" ADD "reset_digest" character varying
   -> 0.0073s
-- add_column(:users, :reset_sent_at, :datetime)
D, [2017-07-17T21:28:47.764156 #4] DEBUG -- :    (1.2ms)  ALTER TABLE "users" ADD "reset_sent_at" timestamp
   -> 0.0015s
== 20170703042006 AddResetToUsers: migrated (0.0089s) =========================

D, [2017-07-17T21:28:47.774368 #4] DEBUG -- :   SQL (6.6ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20170703042006"]]
D, [2017-07-17T21:28:47.776549 #4] DEBUG -- :    (1.8ms)  COMMIT
D, [2017-07-17T21:28:47.792921 #4] DEBUG -- :   ActiveRecord::InternalMetadata Load (3.7ms)  SELECT  "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", :environment], ["LIMIT", 1]]
D, [2017-07-17T21:28:47.798638 #4] DEBUG -- :    (0.9ms)  BEGIN
D, [2017-07-17T21:28:47.802672 #4] DEBUG -- :    (2.9ms)  COMMIT
D, [2017-07-17T21:28:47.804204 #4] DEBUG -- :    (1.3ms)  SELECT pg_advisory_unlock(414146247089748600)
```

###本番環境での動作確認
[１０分メール](https://10minutemail.net/?lang=ja)でアドレスを取得して会員登録を行う。
その後、パスワード再設定を行う。

![image](https://qiita-image-store.s3.amazonaws.com/0/98130/eee2464c-d575-d448-01ac-7af59b3ef0bc.png)


###herokuログ
`heroku logs --tail`でログを確認。

```irb
2017-07-17T21:39:31.530251+00:00 app[web.1]: I, [2017-07-17T21:39:31.530197 #11]  INFO -- : [860a37ff-aacc-4986-9181-c816f0d3a3bd] Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
2017-07-17T21:39:31.530718+00:00 app[web.1]: F, [2017-07-17T21:39:31.530667 #11] FATAL -- : [860a37ff-aacc-4986-9181-c816f0d3a3bd]   
2017-07-17T21:39:31.530777+00:00 app[web.1]: F, [2017-07-17T21:39:31.530725 #11] FATAL -- : [860a37ff-aacc-4986-9181-c816f0d3a3bd] NoMethodError (undefined method `[]' for nil:NilClass):
2017-07-17T21:39:31.530824+00:00 app[web.1]: F, [2017-07-17T21:39:31.530777 #11] FATAL -- : [860a37ff-aacc-4986-9181-c816f0d3a3bd]   
2017-07-17T21:39:31.530896+00:00 app[web.1]: F, [2017-07-17T21:39:31.530824 #11] FATAL -- : [860a37ff-aacc-4986-9181-c816f0d3a3bd] app/controllers/password_resets_controller.rb:10:in `create'
```
###演習１
*production環境でユーザー登録を試してみましょう。ユーザー登録時に入力したメールアドレスにメールは届きましたか?*
１０分メールアドレスでアドレスを取得して会員登録を行う。
メールが届いたことを確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/c8ae18a3-635f-a451-059d-37f8e84cc17f.png)


###演習２
*メールを受信できたら、実際にメールをクリックしてアカウントを有効化してみましょう。また、Heroku上のログを調べてみて、有効化に関するログがどうなっているのか調べてみてください。ヒント: ターミナルからheroku logsコマンドを実行してみましょう。*

アカウントを有効化できることを確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/a179d8cc-51ba-79b4-a848-62101a6b854b.png)

アカウント有効時のログが出力されていることを確認。

```irb
2017-07-19T04:16:04.322404+00:00 app[web.1]: I, [2017-07-19T04:16:04.322291 #7]  INFO -- : [3668efeb-d720-41c2-b708-8249f0213275] Started GET "/account_activations/NK83qY_IcQOSN8pwFmZWHQ/edit?email=lqy57919%40oalsp.com" for 125.199.218.217 at 2017-07-19 04:16:04 +0000
2017-07-19T04:16:04.326858+00:00 app[web.1]: I, [2017-07-19T04:16:04.326749 #7]  INFO -- : [3668efeb-d720-41c2-b708-8249f0213275] Processing by AccountActivationsController#edit as HTML
2017-07-19T04:16:04.326935+00:00 app[web.1]: I, [2017-07-19T04:16:04.326872 #7]  INFO -- : [3668efeb-d720-41c2-b708-8249f0213275]   Parameters: {"email"=>"lqy57919@oalsp.com", "id"=>"NK83qY_IcQOSN8pwFmZWHQ"}
2017-07-19T04:16:04.351571+00:00 app[web.1]: D, [2017-07-19T04:16:04.351460 #7] DEBUG -- : [3668efeb-d720-41c2-b708-8249f0213275]   User Load (1.2ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "lqy57919@oalsp.com"], ["LIMIT", 1]]
2017-07-19T04:16:04.444411+00:00 app[web.1]: D, [2017-07-19T04:16:04.444257 #7] DEBUG -- : [3668efeb-d720-41c2-b708-8249f0213275]   SQL (4.0ms)  UPDATE "users" SET "activated" = 't', "activated_at" = '2017-07-19 04:16:04.438558' WHERE "users"."id" = $1  [["id", 105]]
2017-07-19T04:16:04.447347+00:00 app[web.1]: I, [2017-07-19T04:16:04.447273 #7]  INFO -- : [3668efeb-d720-41c2-b708-8249f0213275] Redirected to http://enigmatic-everglades-70434.herokuapp.com/users/105
2017-07-19T04:16:04.447604+00:00 app[web.1]: I, [2017-07-19T04:16:04.447543 #7]  INFO -- : [3668efeb-d720-41c2-b708-8249f0213275] Completed 302 Found in 121ms (ActiveRecord: 5.9ms)
2017-07-19T04:16:04.448155+00:00 heroku[router]: at=info method=GET path="/account_activations/NK83qY_IcQOSN8pwFmZWHQ/edit?email=lqy57919%40oalsp.com" host=enigmatic-everglades-70434.herokuapp.com request_id=3668efeb-d720-41c2-b708-8249f0213275 fwd="125.199.218.217" dyno=web.1 connect=0ms service=131ms status=302 bytes=975 protocol=http
2017-07-19T04:16:04.862697+00:00 heroku[router]: at=info method=GET path="/users/105" host=enigmatic-everglades-70434.herokuapp.com request_id=3debf180-f75c-4d20-b686-6bd6831ee3b2 fwd="125.199.218.217" dyno=web.1 connect=0ms service=24ms status=200 bytes=2896 protocol=http
2017-07-19T04:16:04.846760+00:00 app[web.1]: I, [2017-07-19T04:16:04.846639 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2] Started GET "/users/105" for 125.199.218.217 at 2017-07-19 04:16:04 +0000
2017-07-19T04:16:04.848792+00:00 app[web.1]: I, [2017-07-19T04:16:04.848712 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2] Processing by UsersController#show as HTML
2017-07-19T04:16:04.848906+00:00 app[web.1]: I, [2017-07-19T04:16:04.848837 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   Parameters: {"id"=>"105"}
2017-07-19T04:16:04.853189+00:00 app[web.1]: D, [2017-07-19T04:16:04.853071 #7] DEBUG -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   User Load (0.9ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 105], ["LIMIT", 1]]
2017-07-19T04:16:04.855994+00:00 app[web.1]: I, [2017-07-19T04:16:04.855886 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   Rendering users/show.html.erb within layouts/application
2017-07-19T04:16:04.857370+00:00 app[web.1]: I, [2017-07-19T04:16:04.857313 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   Rendered users/show.html.erb within layouts/application (1.2ms)
2017-07-19T04:16:04.858613+00:00 app[web.1]: I, [2017-07-19T04:16:04.858558 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   Rendered layouts/_rails_default.html.erb (0.9ms)
2017-07-19T04:16:04.858945+00:00 app[web.1]: I, [2017-07-19T04:16:04.858881 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   Rendered layouts/_shim.html.erb (0.1ms)
2017-07-19T04:16:04.861308+00:00 app[web.1]: D, [2017-07-19T04:16:04.861232 #7] DEBUG -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   User Load (0.8ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 105], ["LIMIT", 1]]
2017-07-19T04:16:04.862347+00:00 app[web.1]: I, [2017-07-19T04:16:04.862272 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   Rendered layouts/_header.html.erb (3.1ms)
2017-07-19T04:16:04.862874+00:00 app[web.1]: I, [2017-07-19T04:16:04.862820 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2]   Rendered layouts/_footer.html.erb (0.2ms)
2017-07-19T04:16:04.863242+00:00 app[web.1]: I, [2017-07-19T04:16:04.863172 #7]  INFO -- : [3debf180-f75c-4d20-b686-6bd6831ee3b2] Completed 200 OK in 14ms (Views: 7.1ms | ActiveRecord: 1.7ms)
2017-07-19T04:16:05.288229+00:00 heroku[router]: at=info method=GET path="/assets/application-89e6500f2055e9eab169c030a3561a92813a5ce017b6e67ab0df3311b0430f3a.js" host=enigmatic-everglades-70434.herokuapp.com request_id=f82893f9-1743-4308-aaf2-4a2fcb2ad63e fwd="125.199.218.217" dyno=web.1 connect=0ms service=2ms status=304 bytes=48 protocol=http
2017-07-19T04:16:07.264932+00:00 heroku[router]: at=info method=GET path="/favicon.ico" host=enigmatic-everglades-70434.herokuapp.com request_id=922625db-fd2d-44ef-8f33-0c34d0bb12cb fwd="125.199.218.217" dyno=web.1 connect=0ms service=2ms status=200 bytes=143 protocol=http
```

###演習３
*アカウントを有効化できたら、今度はパスワードの再設定を試してみましょう。正しくパスワードの再設定ができたでしょうか?*

パスワードの再設定を行う。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/a7fe85d2-db37-ed68-be18-b4ac0d5288a5.png)

パスワード再設定メールが受信できることを確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/f0a44f03-1220-d513-dc67-c1f3f7aa8f2c.png)

パスワードの再設定ができることを確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/98130/0a648a18-6385-4358-bd54-14d5501614da.png)


#おわりに
パスワードリマインダーが完成しました。
本章は、全体的に`password_reset`と書くべき所を、`password_resets`と書いてしまったり、
またその逆があったり、些細なコーディングミスで詰まったことが多い章でした。皆様もお気をつけ下さい。