😺
Rails|お問い合わせフォームの作成
目標
このようなお問い合わせフォームを作成します。
開発環境で実装します。
開発環境
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
}
環境変数の設定
こちらの記事の「メールアドレスとアプリパスワードを環境変数に代入する」を参照
コントローラーの作成
以下のコマンドを実行し、コントローラを作成する。
$ 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>
参考にさせていただいた記事
Discussion