LoginSignup
0
0

More than 1 year has passed since last update.

【Rails】ActionMailerでお問合せフォームを作ろう!!

Last updated at Posted at 2022-08-09

はじめに

お問合せフォームをActionMailerを使って実装する方法を調べ、実装した。

完成予想図
以下のようなものを作る。
①お問合せフォームの作成
スクリーンショット 2022-08-09 22.46.02.png
②確認画面の作成
スクリーンショット 2022-08-09 22.46.18.png
③送信後、ホームへリダイレクト
スクリーンショット 2022-08-09 22.43.59.png
④メールで確認
スクリーンショット 2022-08-09 22.49.00.png

前提

No 項目 内容
1 OS Mac
2 Ruby 2.6.3
3 rails 6.0.4

実装

上記の内容を参考にした。

modelの作成

名前、メールアドレス、問い合わせ内容というカラムのあるモデルを作成する。

ターミナル
# モデル名はcontactなどそれぞれ好きなものを作成すること
$ rails g model staticpage name:string email:string content:text

以下のマイグレーションファイルも作成されたことを確認する。

db/migrate/_create_staticpages.rb
class CreateStaticpages < ActiveRecord::Migration[6.0]
  def change
    create_table :staticpages do |t|
      t.string :name
      t.string :email
      t.text :content

      t.timestamps
    end
  end
end

モデルにバリデーションを設定
下記の内容でバリデーションをかける。

・名前、メールアドレス、内容が空欄でないこと
・名前、メールアドレス、内容の文字数制限
・メールアドレスの正規表現の制限

入力画面で上記のことを守れていないと、エラーが起きる。

staticpage.rb
class Staticpage < ApplicationRecord

  validates(:name,  presence: true, length: { maximum: 50  })
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
  validates(:email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: true)
  validates :content, presence: true, length: { maximum: 500 }

end

routesの設定

ルーティングの設定をする。
下図のような流れで動作するようにする。
スクリーンショット 2022-08-10 0.18.51.png
postリクエストで、入力情報を次のステップに送ることで、それぞれの画面で情報を取り扱っていく。

routes.rb
  get  '/contact', to: 'staticpages#contact'
  post '/confirm', to: 'staticpages#confirm', as: 'confirm'
  post '/back',    to: 'staticpages#back' ,   as: 'back'
  resources :staticpages, only: [:create]

controllerの設定

先ほどの図を実現するため、コントローラーの設定をする。

staticpages_controller.rb
  def contact
    @contact = Staticpage.new
  end

  # contactアクションから入力内容を受け取り、
  # 送信ボタンを押されたらcreateアクションを実行します。
  def confirm
    @contact = Staticpage.new(contact_params)
    # if @contact.invalid?
    #   render :contact
    # end
  end

  # 入力内容に誤りがあった場合、
  # 入力内容を保持したまま前のページに戻るのが当たり前になっているかと思いますが、
  # backアクションを定義することで可能となります。
  def back
    @contact = Staticpage.new(contact_params)
    render :contact
  end

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

  private

  def contact_params
    self.params.require(:staticpage).permit(:name, :email, :content)
  end
end

お問合せテンプレートの作成

お問合せフォームのテンプレートを作成する。
モデルの設定でバリデーションをかけているので、エラーを表示する部分も追加している。

contact.html.erb
<h1>Contact</h1>
<p>
  コンタクトページです。<br>
  お問合せの際は下記より、お願いします。
</p>
<%= form_with(model: @contact, local: true, url: confirm_path) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>

  <%= f.label :name, 'お名前' %>
  <%= f.text_field :name, class: 'form-control', autofocus: true %>

  <%= f.label :email, 'メールアドレス' %>
  <%= f.email_field :email, class: 'form-control' %>
  
  <%= f.label :content, 'お問合せ内容' %>
  <%= f.text_area :content, class: 'form-control long-content' %>

  <%= f.submit '入力内容を確認する', class: "btn btn-primary" %>
<% end %>

エラーメッセージのパーシャルも確認する。

app/views/shared/_error_messages.html.erb
<% if object.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(object.errors.count, "error") %>.
    </div>
    <ul>
    <% object.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>

確認画面テンプレートを作成

入力した内容を確認し、下記を選択することができるテンプレートを作成する。
・OKなら送信
・修正したいなら情報を保持したまま戻る

confirm.html.erb
<h1>確認画面</h1>
<%# 入力した内容を表示するOKなら送信する %>
<%= form_with(model: @contact, local: true) do |f| %>
    <%= f.label :name, 'お名前' %>
    <div class="confirm"><%= params[:staticpage][:name] %></div>
    <%= f.hidden_field :name %>
    <%= f.label :email, 'メールアドレス' %>
    <div class="confirm"><%= params[:staticpage][:email] %></div>
    <%= f.hidden_field :email %>
    <%= f.label :content, 'お問合せ内容' %>
    <div class="confirm"><%= params[:staticpage][:content] %></div>
    <%= f.hidden_field :content %>
  <div><%= f.submit '入力内容を送信する', class: "btn btn-primary" %></div>
<% end %>

<%# 入力内容を修正したいならback_pathに送信すると情報保持してお問合せフォームに戻る %>
<%= form_with(model: @contact, local: true, url: back_path) do |f| %>
  <%= f.hidden_field :name %>
  <%= f.hidden_field :email %>
  <%= f.hidden_field :content %>
  <div><%= f.submit '入力画面に戻る', class: "btn btn-primary" %></div>
<% end %>

上の送信をすると、デフォルトでcreateアクションが実行される(メールが送信される。)。
下の送信をすると、url: back_pathによりbackアクションが実行される。(お問い合わせフォームをレンダリングする。)。下図再掲。
スクリーンショット 2022-08-10 0.18.51.png

mailerの設定

まだ、mailerの設定をしていないため、deliver_nowが発火せず、メールが送信されない。設定していく。

app/mailers/user_mailer.rb
class UserMailer < ApplicationMailer
  def contact(contact)
    @contact = contact
    mail from: contact.email, to: ENV['GMAIL_USER'], subject: "【糖質村】お客様からのお問合せ"
    # => デフォルトでapp/views/user_mailer/contact.html.erb もしくは、app/views/user_mailer/contact.text.erbのテンプレートを探しにいく。
  end
end

引数contactに、お問合せフォームで入力された内容を代入し、保持する。
このデータを次のメールテンプレートで使用する。

メールテンプレートの作成

メールテンプレートを作成し、お問合せを受けた内容をメール本文に記載されるよう設定する。

app/views/user_mailer/contact.html.erb
<h1><%= @contact.name %> 様 からお問い合わせがありました。</h1>
<p>【Mail】: <%= @contact.email %></p>
<p>【お問い合わせ内容】</p>
<span style="white-space: pre-wrap;"><%= @contact.content %></span>
app/views/user_mailer/contact.text.erb
<%= @contact.name %> 様 からお問い合わせがありました。
【Mail】: <%= @contact.email %>
【お問い合わせ内容】
<%= @contact.content %>

環境変数の設定

最後に環境変数の設定をしていく。これをしないと、その環境でmailerを使えない。

以前もActionMailerを使っていたため、環境変数は特に今回いじっていないが一応記載する。

development.rb
  config.action_mailer.asset_host = 'http://localhost:3000'
  config.action_mailer.raise_delivery_errors = true
  host = 'localhost:3000'
  config.action_mailer.default_url_options = { host: host, protocol: 'http' }
  config.action_mailer.delivery_method = :smtp
  ActionMailer::Base.smtp_settings = {
    :port           => 587,
    :address        => 'smtp.gmail.com',
    :user_name      => ENV['GMAIL_USER'],
    :password       => ENV['GMAIL_PASS'], # Googleが発行する、16桁のアプリケーションパスワード
    :domain         => 'gmail.com',
    :authentication => :plain, # 'plain'と書く記事もあり
    :enable_starttls_auto => true
  }
~/.zshrc
# 環境変数
export GMAIL_USER='使用するemail'
export GMAIL_PASS='上記メールのpassword' # アプリパスワード

おわりに

これで、全ての設定を完了し、お問合せ内容がメールで確認できるようになった。

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