【Rails】お問合せフォームの実装

こんにちは！
この記事では、railsで **「お問い合せフォーム」** を実装していきます！
これは、お問い合せフォームを送信すると、設定したメールアドレス宛にお問い合せ内容が送信される機能です。

# ゴール
railsで「お問い合せフォーム」を実装し、gmailにお問合せ内容が届くようにすること。

### 完成イメージ1 （お問合せフォーム）
![スクリーンショット 2022-07-17 1.13.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820462/7f56cc29-f213-c206-476d-8734af657f77.png)

### 完成イメージ2 （設定したGmailにお問合せが届く）
![スクリーンショット 2022-07-17 1.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820462/189dc51a-1d31-8753-52f8-8de308853cfc.png)

# 開発環境
Ruby on Rails 6
ローカルでも本番環境でもどちらも対応
使用できるGmailのアカウント1つ

# 流れ
**1. 事前準備
2. お問合せのページ画面の作成（contacts#new）
3. フォームに情報を入力、送信する実行処理（contacts#create）
4. contact_mailメソッドが実行され、メールが送信される
5. アカウント情報、環境変数の設定**

# 事前準備
**ここは絶対に飛ばさないでください！！！**
### 1.　Gmailの2段階認証設定
Gmailを2段階認証設定する必要があります。以下の記事を参考に送信先に設定するGmailに設定をかけましょう。
https://enjoypclife.net/google-account-gmail-2-step-verification/
※2段階認証にすると、ログインする際に毎回2段階認証が求められるので、めんどくさい！という方は、テスト用にgoogleアカウントを作るといいと思います！
### 2.　未対応のアプリからのログイン用アプリパスワードを持って帰ってくる。
Gmailにログインするために、パスワードを所得する必要があります。最後の方に使用しますが、最初の準備段階で取得しておきましょう。
https://www.howtonote.jp/google-account/2step-verify/index6.html
最終的に、赤線で囲われた12桁のパスワードをメモしておきましょう。
![スクリーンショット 2022-07-16 21.38.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820462/738d6410-173a-a522-f1dd-daf5253996f4.png)

# 実装
実際にお問合せフォームを実装していきます！

## Modelを生成（Contact）
まずはお問合せに関するmodelを作成します。
モデル作成と同時に**name**と**message**カラムも追加します。
他にも電話番号やメールアドレスを所得したければ自由に設定してください！
```
$ rails g model contact name:string message:text
```
実際に作成されたmigrationファイルを確認します。
```ruby: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 :message, null: false
      t.timestamps
    end
  end
end
```
今回特筆すべき点は
- お名前（nullつまり空白は許可しない）
- お問合せの内容（nullつまり空白は許可しない）

この2つです。

マイグレーションも忘れずに行いましょう。
```
$ rails db:migrate
```
ついでにバリデーションも記述していきます。
```ruby:app/models/contact.rb
class Contact < ApplicationRecord
  validates :name, presence: true
  validates :message, presence: true
end
```

これでcontactモデル周りが完成しました。

## Controllerを生成（contacts）
次にお問合せに関するcontrollerを作成します。
```
$ rails g controller contacts
```
続いて、作成したcontrollerにアクションを定義していきます。
```ruby: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).deliver
      redirect_to root_path, notice: 'お問い合わせ内容を送信しました'
    else
      redirect_to new_contact_path
    end
  end

  private

  def contact_params
    params.require(:contact).permit(:name, :message)
  end
  
end
```
それぞれのアクション、ストロングパラメーターに関しては説明を省きます。
特筆すべきは以下の一文で、メール送信の処理を記述しています。
```
ContactMailer.contact_mail(@contact).deliver
```
ここでは、ContactMailerクラスのcontact_mailメソッドを実行します。（今回は@contactの情報を渡しています）
.deliverは「メールを送信してください」という実行の処理で、お問い合わせ内容をデータベースに保存した後、メール送信を行うという流れになっています。

## Viewの作成
お問い合せのビューを作成していきます。
自由に変更してください。
```:app/views/contacts/new.html.erb
  <h1>お問合せフォーム</h1>
  <%= form_with model:@contact do |f| %>
    <p>
      <%= f.label :name,"お名前" %>
      <%= f.text_field :name %>
      <br>
      <%= f.label :message,"お問合せ内容" %>
      <%= f.text_area :message %>
    </p>
    <%= f.submit '送信' %>
  <% end %>
```
ここに関しても、投稿のnewアクションと同様なので、説明は割愛します。

## ルーティングの設定
ルーティングも設定します。
```ruby:app/views/contacts/new.html.erb
Rails.application.routes.draw do
  resources :contacts, only: [:new, :create]
end
```
今回はnewとcreateアクションしか使用しないので、限定しました。


## お問い合せフォームに飛べるようにリンクを設定
お問合せメールに送る為のリンクを配置します。
今回はヘッダーに付けてみましがお好きなページに配置してください。
```app/view/layouts/application.html.erb
<%= link_to 'お問い合せ', new_contact_path %>
```
pathに関しては異なる可能性があるため、routesで確認してもいいですね。
```
$ rails routes
```

## Action Mailerの設定
RailsにはAction Mailerという簡単にメール送信の指示も出すことができる機能が備わっています。
今回はこの機能を利用していきます。

### メーラークラスを作成する
```
$ rails g mailer contact
```
作成された複数のファイルを編集します。
```ruby:app/mailers/contact_mailer.rb
class ContactMailer < ApplicationMailer
   def contact_mail(contact)
      @contact = contact
      mail to: ENV['TOMAIL'], subject: 'お問い合せ内容'
   end
end
```
上記ではmailメソッドでお問い合わせ内容の宛先(to)、タイトル(subject)を設定しています。
本番環境に備えて、環境変数を用いるので、ENV['TOMAIL']はそのまま記述してください。後からメールアドレスの設定を行います。
この「contact_mail」メソッドをコントローラーで呼び出すことで、メール送信が実行されるという流れになっています。

### mailメソッドのオプション
to:の送り先やsubject:の件名のオプション以外に、一般的なメールの機能のオプションがあります。
今回は使用せず、紹介のみに留めておきます。
| Mailメソッドのオプション| 	Mailメソッドオプションの概要 |
| :-: | :-: |
| **from:** | 送信元 |
| **cc:** | CCで、送り先とは直接関係はないが少し知っておいてねという人達の宛先 |
| **bcc:** | ToとCCには知る事はなく、こっそり伝えたい場合の宛先。 |


## サーバーの設定
次にメールサーバーを設定していきます。
今回はGmailのメールサーバーを利用してメール送信を行います。

config/environments/development.rbに以下を記述していきます。
```ruby:config/environments/development.rb
Rails.application.configure do
  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.default_url_options = { host: 'localhost:3000' }
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                  587,
    domain:               'gmail.com',
    user_name:            ENV['SMTP_USERNAME'],
    password:             ENV['SMTP_PASSWORD'],
    authentication:       'plain',
    enable_starttls_auto:  true
    }
end
```
 **「user_name」** に自分のアカウントユーザー名を、　**「password」**　に自分のアカウントパスワードを設定しますが、ここも本番環境に備えて、**環境変数であるENV**を用います。

少し、上記のコードの解説を行います。
上記ではメール送信する上で必要な設定を行っています。

**・config.action_mailer.perform_deliveries = true**
⇒メール送信を有効にする
**・config.action_mailer.raise_delivery_errors = true**
⇒メール送信ができなかった場合、エラーを発生させる
**・config.action_mailer.delivery_method = :smtp**
⇒メール送信する際に通信プロトコルSMTPを利用する

## 環境変数の設定
Gmailアドレスとパスワードを直書きすれば、機能実装は完了ですが、このコードをGithubなどにあげたら全世界にアドレスとパスを公開してしまうことになるのでそれはセキュリティ上よろしくないので環境変数を設定します。
今回は.envという環境変数用ファイルを使う方法を取っていきます。
※他の機能で既に設定している方は、.envに情報を入れるところまで進んでください。

### gemを用意する
```ruby:Gemfile
gem 'dotenv-rails'
```
bundle　installを行います。
```
$ bundle install
```
.envファイルを作成します。（プロジェクトファイル直下）
VSCodeのフォルダーツリーが以下のようになってればOK。
![スクリーンショット 2022-07-16 23.16.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820462/9035db95-efe1-9a4b-b86c-9af1de393926.png)

環境変数を作成していきます。
```ruby:.env
TOMAIL='＜送信先のgmailのメールアドレス＞'

SMTP_USERNAME='＜設定するgmailのメールアドレス＞'
SMTP_PASSWORD='＜Googleで設定した、アプリパスワード＞'
```
ここで、「Googleで設定した、アプリパスワード」は**事前準備**の**2番**で設定したアプリのパスワードを使用します。

最後にアップロードの制限をかけます。.gitignoreに以下を追記しましょう。
```ruby:.gitignore
.env
```
これで環境変数の設定は完了しました！再度serverを立ち上げなおしてアプリの動作確認をしましょう。（まだ完成ではありません！）

## 送信したいメール本文のテンプレートを作成
ここで選択肢が２つあります
①HTML形式で送信する
②テキスト形式で送信する

送信相手によってはHTML形式のメールを受け取ることができない人もいるのでテキスト形式も作成しておくといいかと思います。
app/views/contact_mailer以下に「 contact_mail.text.erb 」を手動で生成してください。
今回はざっくりとお問合せ送信メッセージを作成しました！自由に編集して好みの送信文面を作成してもいいですね！

```:app/views/contact_mailer/contact_mail.text.erb
===============================================
【お問合せ】
お名前：<%= @contact.name %>
お問い合せ内容：<%= @contact.message %>
===============================================
```
結果、以下のようにメールが届いたら完成です！
![スクリーンショット 2022-07-17 1.19.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820462/e41158fd-04df-7ba5-f677-615831155de2.png)


## 参考文献
以下の記事を大変参考にさせてもらいました。ありがとうございます。
https://www.web-knowledge-info.com/wp/ruby-on-rails26/
https://papa-programing.jp/rails-contacts-function/
https://qiita.com/takapon21/items/bd2dd148ad6ae38238f4

## 最後に
今回は、railsで「お問い合せフォーム」を実装しました。
説明が至らない点がたくさんあると思いますが、多めにみてもらえると嬉しいです！

GeekSalonという大学生限定のプログラミングコミュニティではメンターが精力的に記事を書いています！