😺

Rails|お問い合わせフォームの作成

2023/09/10に公開

目標

このようなお問い合わせフォームを作成します。
開発環境で実装します。

開発環境

ruby 3.1.2p20
Rails 6.1.7.4
Cloud9

前提

bootstrapを導入済み
deviseを導入済み(userモデル,adminモデル)

流れ

mailerを作成・編集
モデルを作成
設定ファイルの編集
環境変数の設定
コントローラーの作成
ルーティングの編集
ビューの編集

mailerを作成・編集

以下のコマンドを実行し、メーラーを作成する。

$ rails g mailer ContactMailer

メーラーを以下のように編集する。

app/mailers/contact_mailer.rb
class ContactMailer < ApplicationMailer

  def send_mail(contact)
    @contact = contact
    mail to:   ENV['MAIL_ADDRESS'], subject: '【お問い合わせ】' + @contact.subject
  end

end

send_mail
ここで作成したsend_mailメソッドはコントローラーで使用する。

mail to:
メールの宛先(今回はお問い合わせなので、サイト作成者のメールアドレス)を記入する。
※ここに直接記入するのではなく、後で環境変数で設定すること。

モデルのを作成

以下コマンドを実行し、モデルを作成する。

$ rails g model Contact

マイグレーションファイルに必要なカラムを追記する。

migrate/xxxx_create_contacts.rb
class CreateContacts < ActiveRecord::Migration[6.1]
  def change
    create_table :contacts do |t|

      t.string :name, null: false
      t.string :email, null: false
      t.string :subject, null: false
      t.text :message, null: false

      t.timestamps
    end
  end
end

以下コマンドを実行する。

$ rails db:migrate

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

contact.rb
class Contact < ApplicationRecord

  validates :name, presence: true
  validates :email, presence: true
  validates :subject, presence: true
  validates :message, presence: true

end

設定ファイルの編集

設定ファイルを以下のように編集する。

config/environments/development.rb

config.action_mailer.raise_delivery_errors = true #これは元々falseで記述あり

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'gmail.com',
    user_name: ENV['MAIL_ADDRESS'],
    password: ENV['MAIL_PASSWORD'],
    authentication: 'plain',
    enable_starttls_auto: true
  }

環境変数の設定

こちらの記事の「メールアドレスとアプリパスワードを環境変数に代入する」を参照
https://zenn.dev/airiin/articles/d90bb1d6cdebd8

コントローラーの作成

以下のコマンドを実行し、コントローラを作成する。

$ rails g controller public/contacts new confirm done

コントローラを以下の通り編集する。

controllers/public/contacts_controller
class Public::ContactsController < ApplicationController

  def new
    @contact = Contact.new
  end

  def confirm
    @contact = Contact.new(contact_params)
    if @contact.invalid?
      flash[:alert] = @contact.errors.full_messages.join(", ")
      @contact = Contact.new
      render :new
    end
  end

  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_contacts_path
    else
      flash[:alert] = @contact.errors.full_messages.join(", ")
      @contact = Contact.new
      render :new
    end
  end

  def done
  end

    private

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

ルーティングの編集

ルーティングを以下のように編集する。

routes.rb

resources :contacts, only: [:new, :create] do
  collection do
      post 'confirm'
      post 'back'
      get 'done'
  end
end

ビューの編集

views/public/contacts/new.html.erb
<div class="container-fluid light-blue-container p-5">
  <div class="row">
    <div class="col-md-8 offset-md-2">
    
    <div class="mb-2">
      <%= flash[:alert] %>
    </div>

      <%= form_with model: @contact, url: confirm_contacts_path, local: true do |f| %>
        <div class="form-group">
          <%= f.label :name, 'お名前' %><span class="text-danger">*</span>
          <%= f.text_field :name, autofocus: true, class: 'form-control' %>
        </div>

        <div class="form-group">
          <%= f.label :email, 'メールアドレス' %><span class="text-danger">*</span>
          <%= f.email_field :email, class: 'form-control' %>
        </div>

        <div class="form-group">
          <%= f.label :subject, '件名' %><span class="text-danger">*</span>
          <%= f.text_area :subject, class: 'form-control' %>
        </div>

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

        <div>
          <%= f.submit '入力内容確認', class: "btn btn-outline-info bg-white" %>
        </div>
      <% end %>

    </div>
  </div>
</div>

views/public/contacts/confirm.html.erb
<div class="container p-5">
  <div class="row">
    <div class="col-md-10 offset-md-1">

      <table class="table">
        <tbody>
          <tr>
            <td class="text-right" style="width: 30%;">お名前</td>
            <td><%= @contact.name %></td>
          </tr>
          <tr>
            <td class="text-right mt-3" style="width: 30%;">メールアドレス</td>
            <td><%= @contact.email %></td>
          </tr>
          <tr>
            <td class="text-right mt-3" style="width: 30%;">件名</td>
            <td><%= @contact.subject %></td>
          </tr>
          <tr>
            <td class="text-right mt-3">メッセージ</td>
            <td style="white-space: pre-wrap;"><%= @contact.message %></td>
          </tr>
        </tbody>
      </table>

      <div class="d-flex">
        <div class="mr-3">
        <%= form_with model: @contact do |f| %>
          <%= f.hidden_field :name %>
          <%= f.hidden_field :email %>
          <%= f.hidden_field :subject %>
          <%= f.hidden_field :message %>
          <div><%= f.submit '送信', class: "btn btn-success" %></div>
        <% end %>
        </div>

        <div>
        <%= form_with model: @contact, url: back_contacts_path do |f| %>
          <%= f.hidden_field :name %>
          <%= f.hidden_field :email %>
          <%= f.hidden_field :subject %>
          <%= f.hidden_field :message %>
          <div><%= f.submit '入力画面に戻る', class: "btn btn-info" %></div>
        <% end %>
        </div>
      </div>


    </div>
  </div>
</div>
views/public/contacts/done.html.erb
<div class="container p-5">
  <h5 class="text-center">お問い合わせありがとうございました。</h5>
</div>
views/contact_mailer/send_mail.html.erb, send_text.html.erb
<%= @contact.name %> 様 から問い合わせがありました。<br>

【メールアドレス】:<%= @contact.email %><br>
【件名】:<%= @contact.subject %><br>
【お問い合わせ内容】<br>
<span style="white-space: pre-wrap;"><%= @contact.message %></span>

参考にさせていただいた記事

https://qiita.com/japwork/items/145645e281b81d9bf92c

Discussion