35歳だけどRailsチュートリアルやってみた。[第4版 11章 11.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

##11.4 本番環境でのメール送信
###本章での学び
SendGridを使用して、production環境で実際にメールが送信できるようにする。

####SendGridとは？
詳細は以下URLを参照。

>SendGridは全世界で利用されているメール配信サービスです。
クラウドサービスのためアカウントを作成するだけで即日メールを
送信でき、面倒でコストのかかるメールサーバの構築は不要です。
[SendGridとは](https://sendgrid.kke.co.jp/about/)


####【heroku】アドオンの追加
「SendGrid」のHerokuアドオンを追加する。
1日あたり400通まで無料で送信できるとのこと。

`heroku addons:create`コマンドで追加する。

```irb
yokoyan:~/workspace/sample_app (account-activation) $ heroku addons:create sendgrid:starter
Creating sendgrid:starter on ⬢ enigmatic-everglades-xxxxx... !
 ▸    Please verify your account to install this add-on plan (please enter a credit card) For more information, see https://devcenter.heroku.com/categories/billing Verify now at
 ▸    https://heroku.com/verify
```

利用するためには、クレジットカード登録が必要。
https://heroku.com/verify
にアクセスして、クレジットカードを登録する。

![image](https://qiita-image-store.s3.amazonaws.com/0/98130/5ad06730-de33-3215-8ac0-eb3e241163e5.png)

再度、`heroku addons`コマンドを実行する。

```irb
yokoyan:~/workspace/sample_app (account-activation) $ heroku addons:create sendgrid:starter
 ▸    heroku-cli: This CLI is deprecated. Please reinstall from https://cli.heroku.com
Creating sendgrid:starter on ⬢ enigmatic-everglades-xxxxx... free
Created sendgrid-cubic-30100 as SENDGRID_PASSWORD, SENDGRID_USERNAME
Use heroku addons:docs sendgrid to view documentation
```

####【heroku】production環境のホスト名を確認する
`heroku config`コマンドで環境情報を確認できる


####【config】hostの設定
SendGridアドオンを使用するために、production環境のSMTP情報を追加する。

hostには自分のproduction環境のホスト名を設定する。

```/sample_app/config/environments/production.rb
  # Ignore bad email addresses and do not raise email delivery errors.
  # Set this to true and configure the email server for immediate delivery to raise delivery errors.
  # config.action_mailer.raise_delivery_errors = false
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  host = 'XXXXX.herokuapp.com'
  config_action_mailer.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    :address => 'smtp.sendgrid.net',
    :port => '587',
    :authentication => :plain,
    :user_name => ENV['SENDGRID_USERNAME'],
    :password => ENV['SENDGRID_PASSWORD'],
    :domain => 'heroku.com',
    :enable_starttls_auto => true
  }
```

#####【SendGrid】ユーザ名とパスワードの確認
- ユーザ名

`heroku config:get SENDGRID_USERNAME`で確認できる

```irb
yokoyan:~/workspace/sample_app (account-activation) $ heroku config:get SENDGRID_USERNAME
 ▸    heroku-cli: This CLI is deprecated. Please reinstall from https://cli.heroku.com
xxxxxxx@heroku.com
```

- パスワード

`heroku config:get SENDGRID_PASSEORD`で確認できる

```irb
yokoyan:~/workspace/sample_app (account-activation) $ heroku config:get SENDGRID_PASSWORD
 ▸    heroku-cli: This CLI is deprecated. Please reinstall from https://cli.heroku.com
xxxxxxxxxxxx
```

####【heroku】本番環境へデプロイ
`git push heroku`で本番環境へデプロイを行う。

```irb
yokoyan:~/workspace/sample_app (master) $ git push heroku
Counting objects: 50, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (49/49), done.
Writing objects: 100% (50/50), 9.51 KiB | 0 bytes/s, done.
Total 50 (delta 22), reused 0 (delta 0)
・・・略・・・
remote: Verifying deploy... done.
To https://git.heroku.com/enigmatic-everglades-xxxxx.git
   9d41cab..81be683  master -> master
```

####【heroku】DBのマイグレーション
Usersテーブルに*activation_digest*など、新しいカラムを追加しているため、
production環境のDBマイグレーションを行う。
（マイグレーションを行うことで、ALTER文が発行される）

```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-xxxxx... up, run.4990 (Free)
D, [2017-07-01T06:09:26.475238 #4] DEBUG -- :    (1.7ms)  SELECT pg_try_advisory_lock(414146247089748600);
D, [2017-07-01T06:09:26.492021 #4] DEBUG -- :   ActiveRecord::SchemaMigration Load (6.9ms)  SELECT "schema_migrations".* FROM "schema_migrations"
I, [2017-07-01T06:09:26.515238 #4]  INFO -- : Migrating to AddActivationToUsers (20170618221238)
D, [2017-07-01T06:09:26.517533 #4] DEBUG -- :    (0.9ms)  BEGIN
== 20170618221238 AddActivationToUsers: migrating =============================
-- add_column(:users, :activation_digest, :string)
D, [2017-07-01T06:09:26.541852 #4] DEBUG -- :    (23.7ms)  ALTER TABLE "users" ADD "activation_digest" character varying
   -> 0.0242s
-- add_column(:users, :activated, :boolean, {:dafault=>false})
D, [2017-07-01T06:09:26.544068 #4] DEBUG -- :    (1.8ms)  ALTER TABLE "users" ADD "activated" boolean
   -> 0.0021s
-- add_column(:users, :activated_at, :datetime)
D, [2017-07-01T06:09:26.545461 #4] DEBUG -- :    (1.1ms)  ALTER TABLE "users" ADD "activated_at" timestamp
   -> 0.0014s
== 20170618221238 AddActivationToUsers: migrated (0.0279s) ====================

D, [2017-07-01T06:09:26.550556 #4] DEBUG -- :   SQL (1.7ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20170618221238"]]
D, [2017-07-01T06:09:26.552702 #4] DEBUG -- :    (1.9ms)  COMMIT
D, [2017-07-01T06:09:26.562877 #4] DEBUG -- :   ActiveRecord::InternalMetadata Load (4.1ms)  SELECT  "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", :environment], ["LIMIT", 1]]
D, [2017-07-01T06:09:26.568178 #4] DEBUG -- :    (0.9ms)  BEGIN
D, [2017-07-01T06:09:26.569872 #4] DEBUG -- :    (0.9ms)  COMMIT
D, [2017-07-01T06:09:26.571870 #4] DEBUG -- :    (1.8ms)  SELECT pg_advisory_unlock(414146247089748600)
```

#####動作確認
production環境で実際のメールアドレスを使ってユーザー登録を行う。
自分のメールアドレス宛に有効化メールが送信されたことを確認。

![image](https://qiita-image-store.s3.amazonaws.com/0/98130/5cbe1849-bb9f-eb6d-278b-765cc52c9343.png)

メール内の「Active」リンクをクリックすると、ユーザーが有効化されることを確認。
![image](https://qiita-image-store.s3.amazonaws.com/0/98130/ab12d3c0-8194-83e2-962e-5e503dedd01f.png)


###演習1
*実際に本番環境でユーザー登録をしてみましょう。ユーザー登録時に入力したメールアドレスにメールは届きましたか?*

前述の「動作確認」を参照。

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

`heroku logs`コマンドでproduction環境のログを確認。

- 自分のメールアドレス宛にメールが送信されていること
- 有効化リンクをクリックした後にDB登録されていること

```irb
2017-07-01T06:40:50.186138+00:00 app[web.1]: From: noreply@example.com
2017-07-01T06:40:50.186138+00:00 app[web.1]: To: xxxxxxxx@gmail.com

・・・略・・・
2017-07-01T06:40:50.186164+00:00 app[web.1]: Welcome to the Sample App! Click on the link below to active your account:
2017-07-01T06:40:50.186165+00:00 app[web.1]: 
2017-07-01T06:40:50.186166+00:00 app[web.1]: http://enigmatic-everglades-xxxxx.herokuapp.com/account_activations/F1cbsvdDbmtN6_qhxULo0g/edit?email=xxxxxxxx%40gmail.com

・・・略・・・

2017-07-01T06:40:50.186177+00:00 app[web.1]:   <body>
2017-07-01T06:40:50.186177+00:00 app[web.1]:     <h1>Sample App</h1>
2017-07-01T06:40:50.186178+00:00 app[web.1]: 
2017-07-01T06:40:50.186179+00:00 app[web.1]: <p>Hi yokoyan</p>,
2017-07-01T06:40:50.186179+00:00 app[web.1]: 
2017-07-01T06:40:50.186180+00:00 app[web.1]: <p>
2017-07-01T06:40:50.186180+00:00 app[web.1]:   Welcome to the Sample App! Click on the link below to activate your account:
2017-07-01T06:40:50.186181+00:00 app[web.1]: </p>
2017-07-01T06:40:50.186181+00:00 app[web.1]: 
2017-07-01T06:40:50.186182+00:00 app[web.1]: <a href="http://enigmatic-everglades-xxxxx.herokuapp.com/account_activations/F1cbsvdDbmtN6_qhxULo0g/edit?email=xxxxxxx%40gmail.com">Activate</a>

・・・略・・・

2017-07-01T06:43:34.061568+00:00 heroku[router]: at=info method=GET path="/account_activations/F1cbsvdDbmtN6_qhxULo0g/edit?email=xxxxxxx%40gmail.com" host=enigmatic-everglades-xxxxx.herokuapp.com request_id=f33f17c6-ae8f-43b7-b3cf-e6413865b1de fwd="222.229.53.237" dyno=web.1 connect=0ms service=121ms status=302 bytes=975 protocol=http
2017-07-01T06:43:33.942594+00:00 app[web.1]: I, [2017-07-01T06:43:33.942513 #7]  INFO -- : [f33f17c6-ae8f-43b7-b3cf-e6413865b1de] Started GET "/account_activations/F1cbsvdDbmtN6_qhxULo0g/edit?email=xxxxxxx%40gmail.com" for 222.229.53.237 at 2017-07-01 06:43:33 +0000
2017-07-01T06:43:33.944942+00:00 app[web.1]: I, [2017-07-01T06:43:33.944874 #7]  INFO -- : [f33f17c6-ae8f-43b7-b3cf-e6413865b1de] Processing by AccountActivationsController#edit as HTML
2017-07-01T06:43:33.945049+00:00 app[web.1]: I, [2017-07-01T06:43:33.944962 #7]  INFO -- : [f33f17c6-ae8f-43b7-b3cf-e6413865b1de]   Parameters: {"email"=>"xxxxxxx@gmail.com", "id"=>"F1cbsvdDbmtN6_qhxULo0g"}
2017-07-01T06:43:33.964757+00:00 app[web.1]: D, [2017-07-01T06:43:33.964666 #7] DEBUG -- : [f33f17c6-ae8f-43b7-b3cf-e6413865b1de]   User Load (1.7ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "xxxxxxx@gmail.com"], ["LIMIT", 1]]

・・・略・・・
```

#おわりに
herokuとSendGridアドオンを組み合わせることで、
自分のproduction環境からメール送信を行うことができるようになりました。
また一歩、一般的なWEBサービスに近づいたのは嬉しいです。
SendGridのような便利なクラウドサービスを組み合わせて、これからも開発を進めたいです。