0
0

More than 1 year has passed since last update.

【Rails】Herokuでのお問い合わせフォームの作成方法

Posted at

お問い合わせフォームの実装

利用環境
・ruby 2.7.3
・Rails 6.1.4

前提

お問い合わせフォームでメールを受信するためのメールアドレスを作成
ここではGmailを登録する前提で進めます。

Gmailアカウントの設定

・2段階認証に設定する
・アプリで利用するためのパスワードを作成
 リンク先:https://myaccount.google.com/u/3/security

ActionMailerの設定

本番環境のみでの設定とします。
開発環境でのメール確認に興味がある方はこちらを参考にしてみてください。
https://github.com/fgrehm/letter_opener_web

ターミナル
touch config/initializers/mail.rb
config/initializers/mail.rb
if Rails.env.production?
  # 自身のドメインに置き換えてください
  host = "Herokuのサブドメイン.herokuapp.com"
  # メール配信に失敗した場合にエラーを発生
  ActionMailer::Base.raise_delivery_errors = true
  ActionMailer::Base.delivery_method = :smtp
  ActionMailer::Base.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    port: 587,
    address: "smtp.gmail.com",
    user_name: Rails.application.credentials.gmail[:address],
    password: Rails.application.credentials.gmail[:password],
    domain: host,
    authentication: "plain"
  }
end

サンプルメール

先ほど作成したGmailアドレスをここへ入力します。

app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
  # 送信元として表示するメールアドレスと表示名
  default from: 'アプリ名 <sample@gmail.com>'
  layout 'mailer'
end

お問い合わせ用のメイラーを作成します。

ターミナル
rails g mailer ContactMailer user_email admin_email

上記のコマンド実行によって、HTML形式とtext形式が作成されます。
今回はtext形式のビューのみ使用するのでHTML形式のビューは削除します。

ターミナル
rm -f app/views/contact_mailer/user_email.html.erb app/views/contact_mailer/admin_email.html.erb

お問い合わせフォームの実装

ユーザーがお問い合わせを送信したタイミングでメールを送信できるようにします。

お問い合わせ内容をデータベースに保存できるようモデル・テーブルの作成
迷惑メール対策のためにIPアドレスを保存するカラムも作成

ターミナル
rails g model Contact name:string email:string content:text remote_ip:inet
rails db:migrate

モデルにバリデーションを追加

app/models/contact.rb
class Contact < ApplicationRecord
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

  validates :name, length: { maximum: 48 }
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, length: { maximum: 256 }
  validates :content, presence: true, length: { maximum: 2000 }
  validates :remote_ip, presence: true
end

ユーザーと管理者に送信するよう実装

app/mailers/contact_mailer.rb
class ContactMailer < ApplicationMailer
  ADMIN_EMAIL = "自分のアドレス"

  def user_email(contact)
    @contact = contact
    @name = contact.name.presence || contact.email
    subject = "【アプリ名】お問い合わせを受付いたしました"

    mail(to: contact.email, subject: subject)
  end

  def admin_email(contact)
    @contact = contact
    @name = contact.name.presence || contact.email
    subject = "【アプリ名】お問い合わせがありました"

    mail(to: ADMIN_EMAIL, subject: subject)
  end
end

ユーザーに送信されるメール内容を入力します。

app/views/contact_mailer/user_email.text.erb
<%= @name %> 様

この度は,「アプリ名」にお問い合わせいただき,誠にありがとうございます。
回答の準備が出来次第,担当者よりご連絡いたします。

今後とも「アプリ名」をよろしくお願いいたします。

=*=*=*=*=*=*=*= お問い合わせ内容 =*=*=*=*=*=*=*=

<%= @contact.content %>

=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

当メールの送信アドレスは配信専用となっております。
ご連絡は「お問い合わせフォーム」よりお願いいたします。 

管理者に届くメール内容

app/views/contact_mailer/admin_email.text.erb
<%= @name %> 様より,「アプリ名」にお問い合わせがありました。

=*=*=*=*=*=*=*= お問い合わせ内容 =*=*=*=*=*=*=*=

【氏名】<%= @contact.name %>
【メールアドレス】<%= @contact.email %>
<%= @contact.content %>

=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= 

お問い合わせページの作成

不要なファイルがあれば削除してください。

ターミナル
rails g controller contacts index create --skip-assets --skip-helper --skip-routes
touch config/locales/ja.yml app/views/contacts/_error_messages.html.erb app/views/contacts/_submit_fields.html.erb

ルートに下記を追加

config/routes.rb
resources :contacts, only: %i[index create]
app/controllers/contacts_controller.rb
class ContactsController < ApplicationController
  def index
    @contact = Contact.new
  end

  def create
    @contact = Contact.new(contact_params)
    if @contact.save
      # ユーザーにメールを送信
      ContactMailer.user_email(@contact).deliver_now
      # 管理者にメールを送信
      ContactMailer.admin_email(@contact).deliver_now
      redirect_to root_path
    else
      render :index
    end
  end

  private

  # IPアドレスをパラメータに追加
  def contact_params
    params.require(:contact)
          .permit(:name, :email, :content)
          .merge(remote_ip: request.remote_ip)
  end
end

ビューはとりあえず最低限表示される程度に実装しています。

app/views/contacts/index.html.erb
<h1>お問い合わせ</h1>

<%= form_with model: @contact, local: true do |form| %>
  <%= render "error_messages", form: form %>

  <%= render "submit_fields", form: form %>
  <%= form.submit "送信" %>
<% end %>
app/views/contacts/_error_messages.html.erb
<% if @contact.errors.any? %>
  <div id="error_explanation">
    <h2><%= @contact.errors.count %> つのエラーがあります</h2>

    <ul>
      <% @contact.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>
app/views/contacts/_submit_fields.html.erb
<div>
  <%= form.label :name %> (任意)
  <%= form.text_field :name %>
</div>
<div>
  <%= form.label :email %> (必須)
  <%= form.email_field :email, required: true, pattern: "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]+$" %>
</div>
<div>
  <%= form.label :content %> (必須)
  <%= form.text_area :content, required: true %>
</div>

最後に

とりあえず最低限こんな感じで動きました。
お問い合わせを送信する前の確認画面などを実装するといいかもしれませんね。
いやー長かった・・・。
もしおかしな点がありましたらご指摘お願いします。

0
0
0

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
  3. You can use dark theme
What you can do with signing up
0
0