Railsアプリにお問い合わせフォームを追加

f:id:endoakak:20200725103757j:plain

Railsアプリにお問い合わせフォームを追加しました。お問い合わせがあると、その内容が自分のところにメールで送られてくるようにしました。

今回はこの記事をかなり参考にさせていただきました。

qiita.com

メーラーの作成

RailsにはAction Mailerというものが標準搭載されているらしく、Railsアプリからメールを送るにはこれを使います。

まずは以下のコマンドで必要なファイルを作成します。inquiryの部分はcontactなどお好きな名前で構いません。

% rails g mailer inquiry

f:id:endoakak:20200905090736p:plain

いくつかファイルが生成されますが、重要なのは一つ目のapp/mailers/inquiry_mailer.rbです。

モデルの作成

いったんメーラーは置いておいて、そのほかのファイルを作成していきます。

今回お問い合わせ内容をデータベースに保存する必要はないので、マイグレーションファイルなしでモデルだけを作成します。

% touch app/models/inquiry.rb


ActiveRecordではなくActiveModelを使います。

class Inquiry
  include ActiveModel::Model

  attr_accessor :name, :name_kana, :email, :message

  with_options presence: { message: "を入力してください" } do
    validates :name
    validates :name_kana
    validates :email
    validates :message
  end
end

必要であればバリデーションをもっと細かく設定したり、localeファイルに日本語を追加したりしておくといいと思います。

コントローラーの作成

続いてコントローラーを作成します。

% rails g controller inquiry new edit confirm thanks

今書いてて思ったけどinquiriesの方がいいのかな。inquiryの方がしっくりくるけど、コントローラーの名前は基本複数形で書くって習った気が。

出来上がったコントローラーでアクションを定義していきます。

class InquiryController < ApplicationController
  def new
    @inquiry = Inquiry.new
  end

  def edit
    @inquiry = Inquiry.new(inquiry_params)
  end

  def confirm
    @inquiry = Inquiry.new(inquiry_params)
    render :new unless @inquiry.valid?
  end

  def thanks
    @inquiry = Inquiry.new(inquiry_params)
    InquiryMailer.send_mail(@inquiry).deliver
  end

  private

  def inquiry_params
    params.require(:inquiry).permit(:name, :name_kana, :email, :message)
  end
end

newがお問い合わせフォーム記入画面、confirmが内容確認画面、editは内容修正画面、thanksはお問い合わせありがとうございました画面です。editやconfirmは必要なければなくてもいいと思います。

thanksのところでsend_mailというメソッドを使っていますが、これはあとでメーラーで定義します。

ルーティングの設定

inquiryコントローラーの各アクションへのルーティングを作っておきます。特に複雑なものはないです。

Rails.application.routes.draw do
  get 'inquiry/new'
  post 'inquiry/edit'
  post 'inquiry/confirm'
  post 'inquiry/thanks'end

ビューの作成

new、edit、confirm、thanksそれぞれのビューを作成していきます。

メールを送るための設定

ここからがメーラーの出番です。

まずはapp/mailers/inquiry_mailer.rbにsend_mailメソッドを定義して、メールを送信する際の設定をしていきます。

class InquiryMailer < ApplicationMailer
  def send_mail(inquiry)
    @inquiry = inquiry
    mail(
      to: ENV["GMAIL_ADDRESS"],  # 送信先のアドレス
      subject: 'Webサイトにお問い合わせがありました'  # メールの件名
    )
  end
end

メールアドレスは環境変数に設定した方がいいと思います。

お問い合わせフォーム作成法を紹介しているサイトをいくつか見て気になったのですが、誰から誰にメールを送りたいのかがサイトによって違うので気をつけた方がいいです。

お問い合わせを送ったユーザーに対して「問い合わせを承りました」というメールを送るのか、サイトの管理人に対して「問い合わせがありました」というメールを送るのかで違うので、どっちをやりたいのか意識した方がいいと思います。私が今回やっているのは後者です。

ユーザーに対して送りたければ、送信先のアドレスを@inquiry.mailにすれば大丈夫だと思います。


次に、gmailからメールを送信できるようにします。このメールアドレスからメールを送る、ということですね。

config/initializers/mail.rbというファイルを作成して以下の記述をします。

ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
  address: 'smtp.gmail.com',
  domain: 'gmail.com',
  port: 587,
  user_name: ENV["GMAIL_ADDRESS"],
  password: ENV["GOOGLE_PASSWORD"],
  authentication: 'plain',
  enable_starttls_auto: true
}

SMTPサーバーというメールを送るためのサーバーを使えるようにしているみたいです。詳しいことはわからないです。

これだけではgmail側に怪しいアプリだと判断されて接続を拒否されるので、gmail側で設定が必要になります。

【重要】Google アカウント / Gmail に2段階認証を設定する方法解説!定期的に「セキュリティ診断」も行いましょう! | enjoypclife.net

2段階認証に未対応のアプリからのログイン用にアプリパスワードを生成する | Gmailの使い方

このサイトを参考に、googleアカウントの2段階認証と、アプリからログインするためのパスワードの発行を行いました。


最後に、送信するメールのテンプレートを作成します。

app/views/inquiry_mailer/send_mail.text.erbというファイルを作成して、メールの内容を記述します。

Webサイトからお問い合わせがありました。

--------------------------
名前: <%= @inquiry.name %> (<%= @inquiry.name_kana %>)
Email: <%= @inquiry.email %>
内容:
<%= @inquiry.message %>
--------------------------

これで、お問い合わせフォームを送信したらメールが届くはずです。

今回の私の設定だと、自分のメールアドレスから自分のメールアドレスにメールが届きます。問い合わせがあったことがわかればいいのでこれで十分。

まとめ

  • Railsからメールを送るにはAction Mailerというものを使う
  • DBなしのモデルを作るときはActiveModel
  • メーラーでメールを送るためのメソッドを定義
  • railsからgmailにアクセスするには認証が必要