Railsチュートリアル 第11章 アカウントの有効化 - アカウント有効化のメール送信

# 何をするか

「RailsのAction Mailerライブラリを使って、Userのメイラーを追加する」というのがこの節の内容となります。

以下がポイントとなります。

* 今回実装するメイラーは、Usersコントローラーの`create`アクションにおいて、有効化リンクをメール送信するために用いる
* メイラーの構成は、コントローラーのアクションと類似している
* メールのテンプレートは、ビューと同様の要領で定義できる
    * 今回実装するテンプレートには、有効化トークンとメールアドレス（＝有効にするアカウントのメールアドレス）を含む

# 送信メールのテンプレート

## メイラーの生成

メイラーの生成は、モデルやコントローラー等と同様、`rails generate`で行います。

```
# rails generate mailer UserMailer account_activation password_reset
Running via Spring preloader in process 13442
      create  app/mailers/user_mailer.rb
      invoke  erb
      create    app/views/user_mailer
      create    app/views/user_mailer/account_activation.text.erb
      create    app/views/user_mailer/account_activation.html.erb
      create    app/views/user_mailer/password_reset.text.erb
      create    app/views/user_mailer/password_reset.html.erb
      invoke  test_unit
      create    test/mailers/user_mailer_test.rb
      create    test/mailers/previews/user_mailer_preview.rb
```

今回実装するのは`account_activation`メイラーのほうです。`password_reset`メイラーは、Railsチュートリアルの次章「[第12章 パスワードの再設定](https://railstutorial.jp/chapters/password_reset?version=5.1#cha-password_reset)」で用いるためのメイラーとなります。

### 1つのメイラーに対し、2つのビューのテンプレートが生成される

例えば`account_activation`という1つのメイラーに対し、ビューのテンプレートは、以下の2つ生成されています。

* `account_activation.text.erb`
* `account_activation.html.erb`

`.text.erb`のほうはテキストメール用、`.html.erb`のほうはHTMLメール用のビューのテンプレートとなります。

## 生成されたメイラーの内容

### ビューのテンプレート

```erb:app/views/user_mailer/account_activation.text.erb（テキストメール用のテンプレートの初期状態）
User#account_activation

<%= @greeting %>, find me in app/views/user_mailer/account_activation.text.erb
```

```erb:app/views/user_mailer/account_activation.html.erb（HTMLメール用のテンプレートの初期状態）
<h1>User#account_activation</h1>

<p>
  <%= @greeting %>, find me in app/views/user_mailer/account_activation.html.erb
</p>
```

### メイラーのテンプレート

```ruby:app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  default from: 'from@example.com'
  layout 'mailer'
end
```

`app/mailers/application_mailer.rb`には、アプリケーション全体で共通する実装が記述されています。コントローラーにおける`app/controllers/application_controller.rb`に相当します。

* デフォルトの`from`アドレス
* デフォルトで使われるメイラーのレイアウト

なお、メイラーのレイアウトは、`app/views/layouts`以下に、テキストメール(`mailer.text.erb`)・HTMLメール(`mailer.html.erb`)それぞれで定義されています。

```ruby:app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.user_mailer.account_activation.subject
  #
  def account_activation
    @greeting = "Hi"

    mail to: "to@example.org"
  end

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.user_mailer.password_reset.subject
  #
  def password_reset
    @greeting = "Hi"

    mail to: "to@example.org"
  end
end
```

`app/mailers/user_mailer.rb`は、実際に「アカウントの有効化」や「パスワードの再発行」に際してメールを送信するための動作を実装していくコードです。今回であれば、`account_activation`に対して実装を追加していく、というところですね。

### メイラーのインスタンス変数

メイラーの実装に、`@greeting`というインスタンス変数が登場しています。`@greeting`に限らず、メイラー内で使われるインスタンス変数は、そのままメイラービューでも使うことができます。「コントローラー内で使われるインスタンス変数を、対応するビューで使うことができる」のと同じような感じですね。

## メイラーの実装を変更する

今回の実装内容は以下です。

* fromアドレスのデフォルト値を変更する
* アカウント有効化リンクをメール送信できるようにする

### fromアドレスのデフォルト値を変更する

fromアドレスのデフォルト値は、`app/mailers/application_mailer.rb`から変更します。

```diff:app/mailers/application_mailer.rb
  class ApplicationMailer < ActionMailer::Base
-   default from: 'from@example.com'
+   default from: "noreply@example.com"
    layout 'mailer'
  end
```

### アカウント有効化リンクをメール送信できるようにする

アカウント有効化リンクをメール送信する一連のプロセスは、`app/mailers/user_mailer.rb`に実装していきます。

```ruby:app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer

  def account_activation(user)
    @user = user
    mail to: user.email, subject: "Account activation"
  end

  #...略
end
```

* `account_activation`は1つの引数を取る
    * `account_activation`メソッド内部では、当該引数を`user`という名前で用いる
    * Userモデルのインスタンス
* `@user`というインスタンス変数を定義している
    * `user`をその値とする
    * `@user`は、`account_activation.*.erb`ビューで使うことになる
* メールの宛先は`user`の`email`属性値とする
* メールのタイトルは「Account Activation」とする

## テンプレートビューを実装する

### `edit_account_activation_url`なるアクションの意味

アカウント有効化メールのテンプレートビュー内では、以下のような埋め込みRubyを使うことになります。

```ruby:
edit_account_activation_url(@user.activation_token, ...)
```

#### 復習 - `edit_user_url`の挙動

`edit_user_url`は、以下のような呼び出しに対し…

```ruby:
edit_user_url(user)
```

以下のようなURLを返します。

```
http://www.example.com/users/1/edit
```

このとき、ユーザーIDの「1」は、`params[:id]`として参照することもできます。

#### `edit_user_url`の挙動を踏まえて、`edit_account_activation_url`の挙動

`edit_user_url`の挙動を踏まえ、`edit_account_activation_url`はどういうURLを返すのかを見てみましょう。

例えば、`@user.activation_token`が`"C477rjyLBojP4v5nfKcoqQ"`であるとします（`@user.activation_token`は`User.new_token`の戻り値を使うのでしたね）。すると、`edit_account_activation_url`は以下のURLを返す、ということになります。

```
http://www.example.com/account_activations/C477rjyLBojP4v5nfKcoqQ/edit
```

また、「`@user.activation_token`は、AccountActivationsコントローラーの`edit`アクションにおいて、`params[:id]`として参照できる」というのも重要です。

### アカウント有効化リンクのURLにメールアドレスも組み込む

クエリパラメータを使うことにより、アカウント有効化リンクのURLにメールアドレスも組み込みましょう。以下は、`foo@example.com`という値を、前述アカウント有効化リンクの`email`属性に与える例です。

```
http://www.example.com/account_activations/C477rjyLBojP4v5nfKcoqQ/edit?email=foo%40example.com
```

* クエリパラメータは、「URLの後に`?`に続けて`[属性]=[値]`」という形で与えることができる
    * クエリパラメータを複数与える場合は、`[属性1]=[値1]&amp;[属性]=[値2]&amp;...`という形で与えることができる
* `@`をパーセントエンコーディングの`%40`に変換（エスケープ）してからURL文字列を構成している
    * `@`という文字そのものをURL中で使うことはできないため

#### 名前付きルートのオプションハッシュ

名前付きルートにオプションハッシュを与えると、当該オプションハッシュをクエリパラメータとして展開したURLを得ることができます。オプションハッシュからURLが生成される際、URLで使えない文字は自動でエスケープされ、URLセーフな文字列に変換されます。

```
edit_account_activation_url(@user.activation_token, email: @user.email)
```

`@user.activation_token`の内容が`"C477rjyLBojP4v5nfKcoqQ"`、`@user.email`の内容が`"foo@example.com"`である場合、生成されるURLは「アカウント有効化リンクのURLにメールアドレスも組み込む」項で提示したURLとなります。

#### 余談 - Railsコンソールで、任意の文字列からURLセーフな文字列を得るには

`CGI.escape`というメソッドを使います。

```
# rails console --sandbox

>> CGI.escape("foo@example.com")
=> "foo%40example.com"
```

以下のページの記述を参考にさせていただきました。ありがとうございます。

* [How do I URL-escape a string in Rails? - Stack Overflow](https://stackoverflow.com/questions/6057972/how-do-i-url-escape-a-string-in-rails)

### テンプレートビューの実際の実装

ここまでの説明を踏まえて、テンプレートビューを実際に実装してみましょう。

まずはテキスト形式のテンプレートビューです。

```erb:app/views/user_mailer/account_activation.text.erb
Hi <%= @user.name %>,

Welcome to the Sample App! Click on the link below to activate your account:

<%= edit_account_activation_url(@user.activation_token, email: @user.email) %>
```

続いて、HTML形式のテンプレートビューです。

```erb:app/views/user_mailer/account_activation.html.erb
<h1>Sample App</h1>

<p>Hi <%= @user.name %>,</p>

<p>
Welcome to the Sample App! Click on the link below to activate your account:
</p>

<%= link_to "Activate", edit_account_activation_url(@user.activation_token, email: @user.email) %>
```

「HTML形式のテンプレートでは、リンクを正しく構成するために、`link_to`メソッドを使っている」というのはポイントです。

# 演習 - 送信メールのテンプレート

## 1. コンソールを開き、`CGI`モジュールの`escape`メソッド ([リスト 11.15](https://railstutorial.jp/chapters/account_activation?version=5.1#code-cgi_escape)) でメールアドレスの文字列をエスケープできることを確認してみましょう。このメソッドで`"Don't panic!"`をエスケープすると、どんな結果になりますか?

`CGI.escape`については、項目「余談 - Railsコンソールで、任意の文字列からURLセーフな文字列を得るには」で先に触れましたね。

```
>> CGI.escape("Don't panic!")
=> "Don%27t+panic%21"
```

# 送信メールのプレビュー

## Railsのメールプレビュー機能

Railsには、「特殊なURLにアクセスすることにより、メーラーにより送信されるメールのメッセージ内容をその場でプレビューすることができる」という機能があります。これを「メールプレビュー機能」と呼びます。

例えばdevelopment環境でメールプレビュー機能を利用するには、`config/environments/development.rb`の内容を以下のように変更する必要があります。

```diff:config/environments/development.rb
  Rails.application.configure do
    ...略
    # Don't care if the mailer can't send.
    config.action_mailer.raise_delivery_errors = true
+   config.action_mailer.delivery_method = :test
+   host = 'localhost:3000'
+   config.action_mailer.default_url_options = { host: host, protocol: 'https' }
    ...略
  end
```

### ホスト名について

development環境のメール設定において、ホスト名が必要になる場面があります。当該ホスト名は、各自のdevelopment環境に応じて変更する必要があります。

私自身の開発環境は、「Dockerで仮想環境を構築→仮想環境のディレクトリをローカルのディレクトリにマウント」という形で構築しています。ポート番号の紐付け状況は以下の通りです。

```
>>> docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
705320d4d96d        ruby:2.5.1          "/bin/bash"         4 months ago        Up 3 weeks          0.0.0.0:8080->3000/tcp   rails_tutorial_test
```

「Docker環境の3000番ポートを、ローカルの8080番ポートに紐付ける」という実装になっています。なので、ホスト名は`localhost:3000`になりますね。

## Userメイラーのプレビューファイルの変更

Userメイラーのプレビューファイルの場所は、`test/mailers/previews/user_mailer_preview.rb`となります。

今回実装した`account_activation`メソッドが正常に動作するためには、有効なUserオブジェクトを引数として与える必要があります。そのため、`UserMailerPreview#account_activation`の実装も、自動生成されたものから変更する必要があります。追加する実装は以下のとおりです。

* `account_activation`に渡すために、有効なUserオブジェクトの変数を定義する
* 仮想属性`activation_token`に、有効なトークンを格納しておく

```ruby:UserMailerPreview#account_activation
def account_activation
  user = User.first
  user.activation_token = User.new_token
  UserMailer.account_activation(user)
end
```

また、私の環境は、「Docker環境の3000番ポートを、ローカルの8080番ポートに紐付ける」という実装です。ゆえに、アカウント有効化メールのプレビューをブラウザで見る際には、ポート番号は3000ではなく8080に変える必要もあります。

上記を踏まえた上で、`test/mailers/previews/user_mailer_preview.rb`は以下のように変更していきます。

```diff:test/mailers/previews/user_mailer_preview.rb
- # Preview all emails at http://localhost:3000/rails/mailers/user_mailer
+ # Preview all emails at http://localhost:8080/rails/mailers/user_mailer
  class UserMailerPreview < ActionMailer::Preview

-   # Preview this email at http://localhost:3000/rails/mailers/user_mailer/account_activation
+   # Preview this email at http://localhost:8080/rails/mailers/user_mailer/account_activation
    def account_activation
+     user = User.first
+     user.activation_token = User.new_token
-     UserMailer.account_activation
+     UserMailer.account_activation(user)
    end

    ...略

  end
```

## 実際にアカウント有効化メールをプレビューする

ここまでの実装が完了すれば、指定のURLにアクセスすることにより、アカウント有効化メールをプレビューすることができるようになります。

<img width="895" alt="スクリーンショット 2019-12-05 8.00.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/29822ffd-c8a7-560b-d49b-461472ed5fd4.png">

上記はHTML形式のアカウント有効化メールのプレビューです。

<img width="895" alt="スクリーンショット 2019-12-05 8.00.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/14cdef78-9d92-3fe7-cdbb-6534a7363435.png">

上記はテキスト形式のアカウント有効化メールのプレビューです。

# 演習 - 送信メールのプレビュー

## 1.Railsのプレビュー機能を使って、ブラウザから先ほどのメールを表示してみてください。「Date」の欄にはどんな内容が表示されているでしょうか? 

当該プレビューページを開いた日付・時刻が表示されています。「+0000」とあるので、時刻はUTCです。

また、From:とTo:に指定されたメールアドレスの内容は以下のとおりです。

* From:には`app/mailers/application_mailer.rb`の`default`で指定したメールアドレスが表示されている
* To:にはdevelopment環境の1番目のユーザーのメールアドレスが表示されている
    * `db/seeds.rb`で指定したとおり

# 送信メールのテスト

## 自動生成されたテスト例

`rails generate mailer`では、テストも自動生成されます。

```ruby:test/mailers/user_mailer_test.rb
require 'test_helper'

class UserMailerTest < ActionMailer::TestCase
  test "account_activation" do
    mail = UserMailer.account_activation
    assert_equal "Account activation", mail.subject
    assert_equal ["to@example.org"], mail.to
    assert_equal ["from@example.com"], mail.from
    assert_match "Hi", mail.body.encoded
  end

  test "password_reset" do
    mail = UserMailer.password_reset
    assert_equal "Password reset", mail.subject
    assert_equal ["to@example.org"], mail.to
    assert_equal ["from@example.com"], mail.from
    assert_match "Hi", mail.body.encoded
  end

end
```

## `assert_match`メソッド

Railsのテストで使うことができるメソッドの一つです。このメソッドを使うことにより、正規表現で文字列をテストすることができます。

```ruby:
assert_match 'foo', 'foobar'  # true
assert_match 'baz', 'foobar'  # false
assert_match /\w+/, 'foobar'  # true
assert_match /\w+/, '$#!*+@'  # false
```

## `CGI.escape`メソッド

「演習 - 送信メールのテンプレート」でも登場したメソッドです。今回は、テスト用のユーザーのメールアドレスをエスケープする目的で用います。

```ruby:
CGI.escape(user.email)
```

## 実際のテストの内容

実際のテストの内容は、以下の通りになります。

```ruby:test/mailers/user_mailer_test.rb
require 'test_helper'

class UserMailerTest < ActionMailer::TestCase
  test "account_activation" do
    user = users(:rhakurei)
    user.activation_token = User.new_token
    mail = UserMailer.account_activation(user)
    assert_equal "Account activation", mail.subject
    assert_equal [user.email], mail.to
    assert_equal ["noreply@example.com"], mail.from
    assert_match user.name,              mail.body.encoded
    assert_match user.activation_token,  mail.body.encoded
    assert_match CGI.escape(user.email), mail.body.encoded
  end
end
```

上記テストでは、以下の条件を満たすことをテストしています。また、「`user`の属性値たる文字列については正規表現でテストしている(`assert_match`)」というのもポイントですね。

* メールの題名が「Account Activation」であること
* 宛先メールアドレスが`user`の`email`属性の値であること
* 送信元メールアドレスが`noreply@example.com`であること
* メール本文に、有効化対象ユーザーの以下の属性値が含まれていること
    * ユーザー名(`user.name`)
    * 有効化トークン(`user.activation_token`)
    * メールアドレス(`user.email`)をURLセーフになるようにエスケープした文字列

## 現状では、設定内容に不足があるためテストは通らない

```
# rails test:mailers
Started with run options --seed 41421

ERROR["test_account_activation", UserMailerTest, 2.0582374000223354]
 test_account_activation#UserMailerTest (2.06s)
ActionView::Template::Error:         ActionView::Template::Error: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
            app/views/user_mailer/account_activation.html.erb:9:in `_app_views_user_mailer_account_activation_html_erb__2319365802641605915_47168025798700'
            app/mailers/user_mailer.rb:5:in `account_activation'
            test/mailers/user_mailer_test.rb:8:in `block in <class:UserMailerTest>'

  1/1: [===================================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.07246s
1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
```

```エラーメッセージ抜粋
ActionView::Template::Error: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
```

```erb:app/views/user_mailer/account_activation.html.erb（9行目）
<%= link_to "Activate", edit_account_activation_url(@user.activation_token, email: @user.email) %>
```

「RailsメイラーでフルURLを与える必要があるのに、ホスト名のデフォルト値が設定されていない」という趣旨のエラーメッセージです。今回はtest環境での設定の記述不足なので、`config/environments/test.rb`の内容を追加する必要があります。

「RailsメイラーでフルURLを与える際に用いるホスト名のデフォルト値」は、「`config.action_mailer.default_url_options`に与えるハッシュの`host`属性の値」となります。

```diff:config/environments/test.rb
  Rails.application.configure do
  ...略

    # Tell Action Mailer not to deliver emails to the real world.
    # The :test delivery method accumulates sent emails in the
    # ActionMailer::Base.deliveries array.
    config.action_mailer.delivery_method = :test
+   config.action_mailer.default_url_options = { host: 'example.com' }
    ...略
  end
```

Qiita内においては、@jonnyjonnyj1397さんの「[Rails Missing host to link to! のエラーが出た時](https://qiita.com/jonnyjonnyj1397/items/e31fe746623af74dc5fc)」という記事で、同様の状況について言及されています。

## 今度こそテストは成功する

```
# rails test:mailers
Started with run options --seed 14853

  1/1: [===================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.76254s
1 tests, 9 assertions, 0 failures, 0 errors, 0 skips
```

ここまでの実装が完了し、`config/environments/test.rb`の`config.action_mailer.default_url_options`の設定が完了しているなら、（他にtypo等がなければ）現時点で`test/mailers/user_mailer_test.rb`テストは成功するはずです。

# 演習 - 送信メールのテスト

## 1.この時点で、テストスイートが`green`になっていることを確認してみましょう。

```
# rails test                              
Running via Spring preloader in process 13661
Started with run options --seed 63299

  44/44: [=================================] 100% Time: 00:00:07, Time: 00:00:07

Finished in 7.88171s
44 tests, 192 assertions, 0 failures, 0 errors, 0 skips
```

現時点における全体のテストの結果は以下のようになります。テスト44個・アサーション192個とは、今回Railsチュートリアルで開発中のサンプルアプリケーションも随分と成長したものです。

## 2. [リスト 11.20](https://railstutorial.jp/chapters/account_activation?version=5.1#code-real_account_activation_test)で使った`CGI.escape`の部分を削除すると、テストが`red`に変わることを確認してみましょう。 

`test/mailers/user_mailer_test.rb`の内容を以下のように変更したとしたらどうなるでしょうか。

```diff:test/mailers/user_mailer_test.rb
  require 'test_helper'

  class UserMailerTest < ActionMailer::TestCase
    test "account_activation" do
      user = users(:rhakurei)
      user.activation_token = User.new_token
      mail = UserMailer.account_activation(user)
      assert_equal "Account activation", mail.subject
      assert_equal [user.email], mail.to
      assert_equal ["noreply@example.com"], mail.from
      assert_match user.name,              mail.body.encoded
      assert_match user.activation_token,  mail.body.encoded
-     assert_match CGI.escape(user.email), mail.body.encoded
+     assert_match user.email, mail.body.encoded
    end
  end
```

メイラーに対するテストを実行してみます。

```
# rails test:mailers
Started with run options --seed 22273

 FAIL["test_account_activation", UserMailerTest, 1.0135770000051707]
 test_account_activation#UserMailerTest (1.01s)
        Expected /rhakurei@example\.com/ to match # encoding: US-ASCII
        "...略http://example.com/account_activations/4e6BdYwK0QsIciOrjytusQ/edit?email=rhakurei%40example.com\...略<a href=\"http://example.com/account_activations/4e6BdYwK0QsIciOrjytusQ/edit?email=rhakurei%40example.com\">Activate</a>...略".
        test/mailers/user_mailer_test.rb:13:in `block in <class:UserMailerTest>'

  1/1: [===================================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.01736s
```

「メール本文中に`/rhakurei@example\.com/`という正規表現が見つからない」という趣旨のメッセージを出してテストが失敗していますね。

演習終了後は、`test/mailers/user_mailer_test.rb`の内容は元に戻しておくことを忘れずに。

```diff:test/mailers/user_mailer_test.rb
  require 'test_helper'

  class UserMailerTest < ActionMailer::TestCase
    test "account_activation" do
      user = users(:rhakurei)
      user.activation_token = User.new_token
      mail = UserMailer.account_activation(user)
      assert_equal "Account activation", mail.subject
      assert_equal [user.email], mail.to
      assert_equal ["noreply@example.com"], mail.from
      assert_match user.name,              mail.body.encoded
      assert_match user.activation_token,  mail.body.encoded
-     assert_match user.email, mail.body.encoded
+     assert_match CGI.escape(user.email), mail.body.encoded
    end
  end
```

# ユーザーの`create`アクションを更新

「アプリケーションでメイラーを使い、新規登録ユーザーに対してアカウント有効化のメールを送信する」…以上のユースケースを実現するためには、Usersコントローラーの`create`アクションにも手を加える必要があります。

## 実際に`app/controllers/users_controller.rb`に変更を加える

```diff:app/controllers/users_controller.rb
  class UsersController < ApplicationController
    ...略

    def create
      @user = User.new(user_params)
      if @user.save
-       log_in @user
-       flash[:success] = "Welcome to the Sample App!"
-       redirect_to @user
+       UserMailer.account_activation(@user).deliver_now
+       flash[:info] = "Please check your email to activate your account."
+       redirect_to root_url
      else
        render 'new'
      end
    end

    ...略
  end
```

上記変更のポイントは以下です。

* 新規作成時点では、ユーザーはログインしないようになった
* リダイレクト先をプロフィールページからルートURLに変更
    * プロフィールページへのリダイレクトは、アカウント有効化を実装するにあたっては無意味な動作であるため

## 現状では失敗するテストを一時的にコメントアウトする

上記変更により、現状では、`test/integration/users_signup_test.rb`内のテスト「valid signup information」が成功しない状態になっています。そのため、現状では失敗する以下のテストを一時的にコメントアウトします。

* `users/show`テンプレートが描画されること
    * リダイレクト先をプロフィールページからルートURLに変更したため
* `is_logged_in?`が真であること
    * 新規作成直後にユーザーがログインしない実装にしたため

```diff:test/integration/users_signup_test.rb
  require 'test_helper'

  class UsersSignupTest < ActionDispatch::IntegrationTest

    ...略

    test "valid signup information" do
      get signup_path
      assert_difference 'User.count', 1 do
        post users_path, params: { user: { name: "Example User",
                                          email: "user@example.com",
                                          password: "password",
                                          password_confirmation: "password"} }
      end
      follow_redirect!
-     assert_template 'users/show'
+     # assert_template 'users/show'
      assert_not flash.empty?
-     assert is_logged_in?
+     # assert is_logged_in?
    end
  end
```

## development環境で、この時点で新規ユーザー作成操作を行うと？

<img width="1165" alt="スクリーンショット 2019-12-05 12.37.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323778/89330dc0-8cab-7ab5-6974-498618776cae.png">

きちんとフラッシュメッセージが表示されています。

現状のdevelopment環境においては、実際にメールが送信されることはありません。ただ、生成されたメールの内容はサーバーログに出力されます。以下はサーバーログに出力されたメール内容の例です。

```
Sent mail to foobar.foobar@example.com (29.5ms)
Date: Thu, 05 Dec 2019 03:36:46 +0000
From: noreply@example.com
To: foobar.foobar@example.com
Message-ID: <5de87b4ef1756_34d82af2160b7664722c6@705320d4d96d.mail>
Subject: Account activation
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="--==_mimepart_5de87b4eecb86_34d82af2160b766472131";
 charset=UTF-8
Content-Transfer-Encoding: 7bit


----==_mimepart_5de87b4eecb86_34d82af2160b766472131
Content-Type: text/plain;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

Hi Foo Bar Foobar,

Welcome to the Sample App! Click on the link below to activate your account:

https://localhost:3000/account_activations/RqhnVNn2LxnIwwhzZNUaQg/edit?email=foobar.foobar%40example.com


----==_mimepart_5de87b4eecb86_34d82af2160b766472131
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style>
      /* Email styles need to be inline */
    </style>
  </head>

  <body>
    <h1>Sample App</h1>

<p>Hi Foo Bar Foobar,</p>

<p>
Welcome to the Sample App! Click on the link below to activate your account:
</p>

<a href="https://localhost:3000/account_activations/RqhnVNn2LxnIwwhzZNUaQg/edit?email=foobar.foobar%40example.com">Activate</a>

  </body>
</html>

----==_mimepart_5de87b4eecb86_34d82af2160b766472131--
```

# 演習 - ユーザーの`create`アクションを更新

## 1. 新しいユーザーを登録したとき、リダイレクト先が適切なURLに変わったことを確認してみましょう。その後、Railsサーバーのログから送信メールの内容を確認してみてください。有効化トークンの値はどうなっていますか?

前述「development環境で、この時点で新規ユーザー作成操作を行うと？」における例では、有効化トークンの内容は以下のようになっています。

```
RqhnVNn2LxnIwwhzZNUaQg
```

## 2. コンソールを開き、データベース上にユーザーが作成されたことを確認してみましょう。また、このユーザーはデータベース上にはいますが、有効化のステータスが`false`のままになっていることを確認してください。

```
# rails console --sandbox

>> user = User.last
=> #<User id: 101, ...略, activation_digest: "$2a$10$d8ag86CApZUTMvuuBhlW9uEGbnbYKaKmNV4ynhLEGb8...", activated: false, activated_at: nil>
>> user.activated?
=> false
```

id=101のユーザーは、「development環境で、この時点で新規ユーザー作成操作を行うと？」で新規作成したユーザーです。確かに`user.activated?`の戻り値は`false`です。また、`activated_at`の値は`nil`です。