search
LoginSignup
40

More than 1 year has passed since last update.

posted at

updated at

【Ruby on Rails】お問合せフォームの作成

目標

このような問い合わせフォームを作成します。
今回は開発環境でgmail宛に送信する方法です。
問い合わせ.png

開発環境

ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

前提

※ ▶◯◯ を選択すると、説明等が出てきますので、
  よくわからない場合の参考にしていただければと思います。

bootstrap4導入済み

【Ruby on Rails】enumを日本語表記にする方法
お問い合わせ件名の選択に使用します。_i18nが使用されている箇所です。

流れ

1 mailerを作成、編集
2 テーブルの作成
3 config/enviroments/development.rbの編集
4 環境変数の設定
5 controllerの作成
6 routing編集
7 viewの編集
8 googleアカウントで安全性の低いアプリのアクセスを許可する

mailerを作成、編集

ターミナル
$ rails g mailer ContactMailer

送信先と件名を指定します。
ENV['TOMAIL']は後ほど設定します。

app/mailers/contact_mailer.rb
class ContactMailer < ApplicationMailer
  def send_mail(contact)
    @contact = contact
    mail to:   ENV['TOMAIL'], subject: '【お問い合わせ】' + @contact.subject_i18n
  end
end

テーブルの作成

ターミナル
$ rails g model Contact

カラムは必要なものを追加してください。
enumの設定については次回記事で解説します。

db/migrate/xxxxxxxxxxxxx_create_contacts.rb
class CreateContacts < ActiveRecord::Migration[5.2]
  def change
    create_table :contacts do |t|
      t.string :name, null: false
      t.string :email, null: false
      t.string :phone_number, null: false
      t.integer :subject, default: 0, null: false
      t.text :message, null: false

      t.timestamps
    end
  end
end

config/enviroments/development.rbの編集

config/enviroments/development.rb

...

config.action_mailer.raise_delivery_errors = false 
 ↓ true に変更
config.action_mailer.raise_delivery_errors = true

...

config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
      port: 587,
      address: 'smtp.gmail.com',
      domain: 'smtp.gmail.com',
      user_name: ENV['SMTP_USERNAME'],
      password: ENV['SMTP_PASSWORD'],
      enable_starttls_auto: true
  }
end

環境変数の設定

今回はGitHub上にアドレスとパスワードをアップしないよう
gem "dotenv-rails"を使用します。

Gemfile
gem "dotenv-rails"
ターミナル
$ bundle install

次にGemfileと同じ階層に .envファイルを作成

.env
TOMAIL=送信先のアドレス

SMTP_USERNAME=送信元のgmailアドレス
SMTP_PASSWORD=送信元のgmailアドレスのパスワード

失敗談【SMTP_USERNAME】
はじめにSMTP_USERNAMEをMAILと設定しようとしたところ、
何度やってもエラーになりました。
なので、設定する際にはこのように表記をした方がいいかもしれません。
命名規則を勉強した上でまた更新したいと思います。

.gitignoreファイルの一番下に下記を追加。

.gitignore
/.env

controllerの作成

ターミナル
$ rails g controller contacts
app/controllers/contacts_controller.rb
class Public::ContactsController < ApplicationController
  def new
    @contact = Contact.new
  end

  # 確認画面を作成する場合はこのような記述になるかと思います。
  # newアクションから入力内容を受け取り、
  # 送信ボタンを押されたらcreateアクションを実行します。
  def confirm
    @contact = Contact.new(contact_params)
    if @contact.invalid?
      render :new
    end
  end
 
  # 入力内容に誤りがあった場合、
  # 入力内容を保持したまま前のページに戻るのが当たり前になっているかと思いますが、
  # backアクションを定義することで可能となります。
  def back
    @contact = Contact.new(contact_params)
    render :new
  end

  # 実際に送信するアクションになります。
  # ここで初めて入力内容を保存します。
  # セキュリティーのためにも一定時間で入力内容の削除を行ってもいいかもしれません。
  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      ContactMailer.send_mail(@contact).deliver_now
      redirect_to done_path
    else
      render :new
    end
  end

  # 送信完了画面を使用する場合お使いください。
  def done
  end

  private

  def contact_params
    params.require(:contact)
          .permit(:email,
                  :name,
                  :phone_number,
                  :subject,
                  :message
                 )
  end
end

routing編集

config/routes
resources :contacts, only: [:new, :create]
post 'contacts/confirm', to: 'contacts#confirm', as: 'confirm'
post 'contacts/back', to: 'contacts#back', as: 'back'
get 'done', to: 'contacts#done', as: 'done'

viewの編集

app/views/contact_mailer配下に
send_mail.html.erb
send_text.html.erb を作成してください。
※なぜ2つ作成するかはわからないので、未来の自分に託したいと思います。。。
内容は同じ内容を記入してください

app/views/contact_mailer/send_mail.html.erb,send_text.html.erb
<%= @contact.name %> 様 から問い合わせがありました。<br>
【Tel】:<%= @contact.phone_number %><br>
【Mail】:<%= @contact.email %><br>
【用件】:<%= @contact.subject_i18n %><br>
【お問い合わせ内容】<br>
<span style="white-space: pre-wrap;"><%= @contact.message %></span>

実際の入力フォームを作成していきます。
※名前とmessageのみ記述します。

app/views/contacts/new.html.erb

<%= form_for(@contact, url: confirm_path) do |f| %>
  <div class="form-group">
    <%= f.label :name, 'お名前*' %>
    <%= f.text_field :name, autofocus: true, class: 'form-control' %>
  </div>

  <div class="form-group">
    <%= f.label :message, 'メッセージ*' %>
    <%= f.text_area :message, size: '10x10', class: 'form-control' %>
  </div>

  <div>
    <%= f.submit '入力内容確認' %>
  </div>
<% end %>

確認画面から入力画面に戻るコードを記述します。
※名前とmessageのみ記述します。

app/views/contacts/confirm.html.erb

<table>
  <tbody>
    <tr>
      <td class="text-center" style="width: 30%;">お名前</td>
      <td><%= @contact.name %></td>
    </tr>
    <tr>
      <td class="text-center">メッセージ</td>
      <td style="white-space: pre-wrap;"><%= @contact.message %></td>
    </tr>
  </tbody>
</table>

<%= form_for(@contact) do |f| %>
  <%= f.hidden_field :name %>
  <%= f.hidden_field :email %>
  <%= f.hidden_field :phone_number %>
  <%= f.hidden_field :subject %>
  <%= f.hidden_field :message %>
  <div><%= f.submit '送信' %></div>
<% end %>
<%= form_for @contact, url: back_path do |f| %>
  <%= f.hidden_field :name %>
  <%= f.hidden_field :email %>
  <%= f.hidden_field :phone_number %>
  <%= f.hidden_field :subject %>
  <%= f.hidden_field :message %>
  <div><%= f.submit '入力画面に戻る' %></div>
<% end %>

補足【<%= @contact.name %>】
new画面のフォームでconfirmアクションに飛ばしているため、
paramsでは@contactに値が入っている状態が作れています。
したがって保存せずとも表示が可能です。

補足【送信】
@contactで表示はされているものの、保存は出来ていない状態です。
このままcreateアクションに飛ばしてしまうと保存されない状態でparamsを投げてしまいます。
そこでf.hidden_fieldを使い、それぞれparamsを再代入し、createに飛ばしています。

補足【入力画面に戻る】
こちらは送信と同じ理由になりますので、上記をご確認ください
@contactで表示はされているものの、保存は出来ていない状態です。

googleアカウントで安全性の低いアプリのアクセスを許可する

Google 安全性の低いアプリのアクセスを有効にする方法
こちらの記事がわかりやすかったので参考にしてください。

参考

まとめ

個人のアドレスや電話番号を扱うことになるため、
プライバシーポリシーや定期的な情報の削除は必須だと思います。
しかし、メールを相手に自動的に送信できるのは様々なこtにおいて優先順位は高めだと思いますので、
しっかり理解したほうがいいかもしれません。

またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
40