目標
このような問い合わせフォームを作成します。
今回は開発環境でgmail宛に送信する方法です。
開発環境
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']は後ほど設定します。
class ContactMailer < ApplicationMailer
def send_mail(contact)
@contact = contact
mail to: ENV['TOMAIL'], subject: '【お問い合わせ】' + @contact.subject_i18n
end
end
テーブルの作成
$ rails g model Contact
カラムは必要なものを追加してください。
enumの設定については次回記事で解説します。
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.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"を使用します。
gem "dotenv-rails"
$ bundle install
次にGemfileと同じ階層に .envファイルを作成
TOMAIL=送信先のアドレス
SMTP_USERNAME=送信元のgmailアドレス
SMTP_PASSWORD=送信元のgmailアドレスのパスワード
失敗談【SMTP_USERNAME】
はじめにSMTP_USERNAMEをMAILと設定しようとしたところ、 何度やってもエラーになりました。 なので、設定する際にはこのように表記をした方がいいかもしれません。 命名規則を勉強した上でまた更新したいと思います。.gitignoreファイルの一番下に下記を追加。
/.env
controllerの作成
$ rails g controller contacts
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編集
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つ作成するかはわからないので、未来の自分に託したいと思います。。。
内容は同じ内容を記入してください
<%= @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のみ記述します。
<%= 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のみ記述します。
<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 安全性の低いアプリのアクセスを有効にする方法
こちらの記事がわかりやすかったので参考にしてください。
#参考
- Railsとメール送信あれやこれや
- Ruby OnRailsで環境変数を使用する方法 ※英語です
- シンプルにお問い合わせ機能を実装する
- rails でお問合せフォームを作り、自分のメールアドレスに送信させる方法
まとめ
個人のアドレスや電話番号を扱うことになるため、
プライバシーポリシーや定期的な情報の削除は必須だと思います。
しかし、メールを相手に自動的に送信できるのは様々なこtにおいて優先順位は高めだと思いますので、
しっかり理解したほうがいいかもしれません。
またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork