【rails6】お問合せフォームの実装（メール送信を含む）

こんばんは！
今日は「　**お問合せフォーム**　」を実装していきます。

この機能は下記のフローを経ます
①お問合せフォームのページへ遷移する
②フォームを入力、送信ボタンを押す
③入力された内容が登録しているメールに届く（管理人にもbccで届く）

## こんな機能を実装します
では、完成した動画からご覧くださいませ

①お問合せフォームのページへ遷移する
![ea24023244e9b88ce6bca957f803950a](https://user-images.githubusercontent.com/80019801/122075008-aeba5380-ce34-11eb-84fb-146c8c6a4d78.gif)

②フォームを入力、送信ボタンを押す
![990aa8eeddf42cff53d36c1430ccc07b](https://user-images.githubusercontent.com/80019801/122075481-11abea80-ce35-11eb-8387-4b707864c076.gif)

③入力された内容が登録しているメールに届く（管理人にもbccで届く）
![4c325f983a957293a446372a19878e85](https://user-images.githubusercontent.com/80019801/122075808-4f107800-ce35-11eb-9825-8dc56f1e285e.gif)

では、一緒にやっていきましょう！

## 環境
- Ruby on Rails 6.0
- ローカルでも本番環境でもどちらも対応します
- 使用できるGmailのアカウント1つ
- テスト利用するGmailは2段階認証を設定しておきましょう

## 事前準備
テストで利用するGmailに、2段階認証まで設定する必要があります。
（あくまでも自分向けですが、できる限りお客様にもお願いした方が良いかと思います）


下記の記事を参考に、まずはGmailの設定を行ってください
そして、未対応のアプリからのログイン用アプリパスワードを持って帰ってきてくださいませ
※飛ばさないこと！！※

https://enjoypclife.net/google-account-gmail-2-step-verification/
https://www.howtonote.jp/google-account/2step-verify/index6.html


## 実装していきましょう
それでは、お問合せフォームを実装していきましょう！

### お問合せに関するモデルとコントローラーを生成（Contact）
まずはお問合せに関するモデルを作成します

```
% rails g model contact
```

必要な情報は、
- お名前（nullは許可しない）
- お問合せの内容（nullは許可しない）
この二つです。

```db/migrate/_create_contacts.rb
class CreateContacts < ActiveRecord::Migration[6.0]
  def change
    create_table :contacts do |t|
      t.string :name, null: false
      t.text :content, null: false
      t.timestamps
    end
  end
end
```
記述できましたらマイグレーションも実施しましょう
その次はバリデーションを記述していきます

```app/models/contact.rb
class Contact < ApplicationRecord
  validates :name, presence: true
  validates :content, presence: true
end
```
ここまで簡単ですね！

次はコントローラーを生成します

```
% rails g controller contacts
```

今回のcontactsコントローラーで必要なアクションは「newとcreate」のみです

```app/controllers/contacts_controller.rb
class ContactsController < ApplicationController

  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.contact_mail(@contact, current_user).deliver
      redirect_to root_path, notice: 'お問い合わせ内容を送信しました'
    else
      render :new
    end
  end


  private

    # Only allow a list of trusted parameters through.
    def contact_params
      params.require(:contact).permit(:name, :content)
    end
end
```

とりあえず書くだけ書いてください！！
詳細は改めます

### お問合せのビューを作成します
では、お問合せのビューを作成していきましょう。
私のは参考までにご覧くださいませ

```app/views/contacts/new.html.erb
<%= form_with(model: @contact, local: true) do |f| %>
    <%= render "shared/second-header"%>
    <div class='form-wrap'>
      <div class='form-header'>
        <h5 class='form-header-text'>
          お問い合わせフォーム
        </h5>
      </div>
    </div>
    <div class="correct-msg-box">
      <% if @contact.errors.any? %>
        <div id="error_explanation">
          <ul><% @contact.errors.full_messages.each do |message| %>
            <li><%= message %></li>
            <% end %>
          </ul>
        </div>
      <% end %>
      <div class="correct-msg-main">
        <div class="contact-form">
            <div class="correct-text-field">
              <%= f.label "お名前" %>
              <%= f.text_field :name, placeholder: "お名前", class: "input-form" %>
            </div>
            <div class="correct-text-field">
              <%= f.label "お問合せ内容" %>
              <%= f.text_area :content, placeholder: "お問合せ内容を入力してください", class: "input-form" %>
            </div>
            <div class="send-btn-contents">
              <div class="register-btn">
                <%= f.button type: "submit", class:"register-red-btn", style:'border-style: none;' do %> 
                  送信 <i class="fas fa-paper-plane"></i>
                <% end %>
              </div>
              <div class="register-btn">
                <%= link_to "もどる", root_path, class:"register-red-btn", style:"background-color: #aaa" %>
              </div>
            </div>
        </div>
      </div>
  </div>
<% end %>
```

一旦はこれでいいでしょう。

ルーティングも設定します

```config/routes.rb
Rails.application.routes.draw do
  resources :contacts, only: [:new, :create]
end
```

さてこれで準備は最後です
お問合せメールに入る為のリンクを作ります

```_header.html.erb
<%= link_to new_contact_path( user_id: current_user.id ) %>
```

では、次からはメールが送信できる様に設定をしていきます

### Action Mailerの設定をします
RailsにはAction Mailerという機能が備わっています
簡単にメール送信の指示も出すことができるんですよ
一緒に設定していきましょう！

### メーラークラスを作成する
まずはターミナルで下記を入力してください

```
% rails g mailer contact
```

生成された複数のファイルをいじっていきましょう

```app/mailers/contact_mailer.rb
class ContactMailer < ApplicationMailer

  def contact_mail(contact, user)
    @contact = contact
    mail to: user.email, bcc: ENV["ACTION_MAILER_USER"], subject: "お問い合わせについて【自動送信】"
  end
end
```

一つずつ解説していきます

このファイル内で「お問合せに関するメール送信　 = contact_mail」メソッドを作成していきます。（命名は自由です）
次に、

```
@contact = contact
```
これはビューファイルで@contactを使用するために設定しました。
邪魔であれば書かなくても大丈夫です


```
mail to: user.email, bcc: ENV["ACTION_MAILER_USER"], subject: "○○"
```

- mail メールを送信します
- to: 送信先を指定します　=> お問合せをしたuserの登録メールアドレスに送付します
- bcc: 必要な場合のみccとbccを設定しましょう。ここには私のメールアドレスが入っています
- subject: メールのタイトルは○○にします

という意味になります  

この「contact_mail」メソッドをコントローラーで呼び出すことで、メール送信が走る
という流れになりますよ

## アプリケーションの設定をしていく
config/environments/development.rbに記述していきます

```config/environments/development.rb
Rails.application.configure do
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                  587,
    domain:               'gmail.com',
    user_name:            ENV["ACTION_MAILER_USER"],
    password:             ENV["ACTION_MAILER_KEY"],
    authentication:       'plain',
    enable_starttls_auto:  true
   }
end
```

分解していきます

```
config.action_mailer.raise_delivery_errors = true
```
→ メール送信ができなかった場合、エラーを発生させます

```
config.action_mailer.delivery_method = :smtp
```
→ メール送信時は通信プロトコルSMTPを使用します

その下、SMTPの設定はコピペでも構いません
ここの情報は送信元に該当しますので取り扱いにはご注意くださいませ

### 送信したいメール本文のテンプレートを作成します

ここで選択肢が２つあります
①HTML形式で送信する
②テキスト形式で送信する

HTMLでメールを受信したくない場合も想定されますので、テキスト形式がいいかもしれませんね
app/views/contact_mailer以下に「 contact_mail.text.erb 」を生成してください

```app/views/contact_mailer/contact_mail.text.erb
<%= @contact.name%>様

  いつもご利用いただき誠に有難うございます。
  また、お問合せのメールを頂き誠に有難うございます。

  ===============================================

  【お問合せ内容】
  <%= @contact.content %>

  ===============================================

  頂きましたお問合せ内容につきましては、内容を確認の上早急に対応致します。
  お時間少々頂戴できますと幸甚でございます。

  また、今後とも当アプリケーションをどうぞよろしくお願い申し上げます。

  --------------------
  運営事務局
  責任者： ○○
  E-mail: ○○@example.com
  電話番号：000-0000-0000
  住所：〒000-0000  東京都○○区△△町0-0-0
  --------------------
```
こんな感じでどうでしょう？雰囲気だけでも本格的に作成しました

### コントローラーからメール送信の処理を実行させる
では、記述済みのコントローラーにメール送信の処理を書いていきます

```
ContactMailer.contact_mail(@contact, current_user).deliver
```
この部分です

ContactMailerクラスのcontact_mailメソッドを実行します（２つ情報を渡します）
.deliverは「メールを送信してくださいね」の実処理部分と覚えておいてください

これでメール送信することができました  


一応今回の処理の流れをまとめておきましょう

- お問合せのページに遷移する（contacts#new）
- フォームに情報を入力、送信する（contacts#create）
- contact_mailメソッドが実行され、メールが送信される

これでご理解いただけましたでしょうか？
長丁場お疲れ様でした

もし、メールが届かない！！
という方は参考文献から、Gem「“letter_opener_web”」を活用してみてください

ではまた次回お会いしましょう！



### 参考文献
https://papa-programing.jp/rails-contacts-function/

https://qiita.com/YJ2222/items/fcf21b6a33721ede13e5