Railsチュートリアル 第１１章＜復習＞

第１１章の復習メモです。
個人的に重要と思ったことを書きます。

前回と同様、以下３つの視点で書きます。

- 分かったこと
- 分からなかったこと
- 今回はスルーしたこと


#分かったこと

##メール送信について

###メールによるアカウント有効化
新規登録されたユーザーのアカウントは、初期状態では無効にしておく。アカウント有効化のリンクが付いたメールをユーザに送り、リンクがクリックされたら有効化する。流れは以下の通り。

1. ユーザーの初期状態は「有効化されていない」(unactivated) にしておく。
2. ユーザー登録が行われたときに、有効化トークンと、それに対応する有効化ダイジェストを生成する。
3. 有効化ダイジェストはデータベースに保存しておき、有効化トークンはメールアドレスと一緒に、ユーザーに送信する有効化用メールのリンクに仕込んでおく。
4. ユーザーがメールのリンクをクリックしたら、アプリケーションはメールアドレスをキーにしてユーザーを探し、データベース内に保存しておいた有効化ダイジェストと比較することでトークンを認証する。
5. ユーザーを認証できたら、ユーザーのステータスを「有効化されていない」から「有効化済み」(activated) に変更する。

###ルーティング
アカウント有効化に関する処理を行うコントローラ`AccountActivationsコントローラ`を生成する。

```
$ rails generate controller AccountActivations
```

また、ルーティングに自動生成処理を追記する。

```config/routes.rb
Rails.application.routes.draw do
  root   'static_pages#home'
  get    '/help',    to: 'static_pages#help'
  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'
  resources :users
  resources :account_activations, only: [:edit] # ← 自動生成処理を追記
end
```

アカウントの有効化処理は、RESTのルールに従うと、（DB値の変更を伴うので）**PATCHリクエスト→updateアクション**で行われるべき。しかし今回は、上の手順4の通り、ユーザーがリンクをクリックすることでリクエストが発生するため、**PATCHリクエストではなくGETリクエストになってしまう**。よって今回は、**GETリクエスト→editアクション**に変更した。

###メイラーの作成
Railsでメールを送信するには、**メイラー**を使う。メイラーは`generate mailer`コマンドで生成する。

```
$ rails generate mailer UserMailer account_activation password_reset
```

このコマンドを実行することで、メイラー、テンプレートが生成される。

- Applicationメイラー

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

`default from: "noreply@example.com"`が、送り主のメールアドレスを表す。

- Userメイラー

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

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

  def password_reset
    @greeting = "Hi"

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

`account_activation`メソッドの引数で、Userオブジェクトを受け取り、`mail to: user.email`でメールの送り先に設定している。また、`subject: "Account activation"`がメールの件名になる。（password_resetメソッドは次章で使う）

- テキストメール用のテンプレート

```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メール用のテンプレート

```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) %>
```

`link_to`メソッドの第二引数で、アカウント有効化のURLを生成している。以下のURLが生成される。

`account_activations/q5lt38hQDc_959PVoo6b7A/edit?email=foo%40example.com`

このURLが生成される仕組みは、以下のルーティング表を参照。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506678/7fa37764-6c8e-b604-5da3-c929497ecc2d.png)


#分からなかったこと、今回はスルーしたこと

- メールのプレビュー表示
- 本番環境でのメール送信
- テスト全般
- アプリケーションの仕様、ロジックの詳細