次からもっとスムースにできるように、ここに執筆します。
前提
- バージョンは
Rails 5.2.3
です。 - テンプレートエンジンはHamlを使っていますが、ERBでもSlimでもそんなに変わらないはずです。
$ rails -v
Rails 5.2.3
要件(仕様、やりたいこと)
- 問い合わせフォームで必要事項を入力して送信すると、その内容をDBに保存するとともに、管理者にテキストメールで通知する。
letter_opener を導入する
- letter_opener というgemを導入すると、開発中にテストで送信したメールが実際にアドレス先に飛んでいく代わりに、ブラウザのポップアップで確認できるようになります。
- 導入することで、テスト用のメールが誤って実際に使われているアドレス先に送信されるのを防ぐことができます。
- 実際にやってみればどうなるかわかると思いますので、とりあえず以下の手順で導入だけ済ませておきます。
Gemfile
group :development do
gem 'letter_opener'
end
$ bundle install
config/environments/development.rb
config.action_mailer.delivery_method = :letter_opener
実装
では実装していきます。
config/environments/development.rb
を編集する
-
config.action_mailer.raise_delivery_errors = false
をコメントアウトすることで、development環境からもメールを送信する設定に切り替えることができます。 -
config.action_mailer.delivery_method
は先ほど追加した部分です。 -
config.action_mailer.default_url_options
は、後述のメールテンプレート内でURLヘルパーを使用できるようにする設定です。
config/environments/development.rb
Rails.application.configure do
#...(中略)...
# コメントアウトすることでdevelopment環境からもメールを送信する設定になる
# config.action_mailer.raise_delivery_errors = false
# smtpで実際にメール送信させるのではなく、letter_openerというgemを用いてテストする
# config.action_mailer.delivery_method = :smtp
config.action_mailer.delivery_method = :letter_opener
# メールテンプレートはviewと違ってURLヘルパーを使ってもドメインが取得できず、メール本文にURLを載せられないので、その対策をする
config.action_mailer.default_url_options = {:host => 'localhost:3000'}
end
メーラークラスを作成する
-
rails generate
コマンドが使用できます。 - 今回はHTMLメールではなくテキストメールを実装したいため、
app/views/notice_mailer/sendmail_contact.html.haml
は削除します(HTMLテンプレートの方が優先して呼ばれるみたいなので、そちらを残しておくとエラーになったり意図しない内容のメールになってしまいます)。
$ rails g mailer Notice sendmail_contact
Running via Spring preloader in process 1180
create app/mailers/notice_mailer.rb
invoke haml
create app/views/notice_mailer
create app/views/layouts/mailer.text.haml
create app/views/layouts/mailer.html.haml
create app/views/notice_mailer/sendmail_contact.text.haml
create app/views/notice_mailer/sendmail_contact.html.haml ->削除する
- メーラークラスは以下の内容にします。
- 送信元アドレスは実際に存在しないアドレスでも構いません。ここに入れたアドレスが実際に送られるメールのfromに入ってきます。
- 送信先アドレスには実際に送りたいアドレスを指定します。当然ですが存在するアドレスを入れる必要があります(以下のコードでは例として
admin@example.com
を入れています)
app/mailers/notice_mailer.rb
class NoticeMailer < ApplicationMailer
# メール送信元アドレスを設定する
default from: "noreply@example.com"
def sendmail_contact(contact)
@contact = contact
# メール送信先アドレスを設定する
mail to: "admin@example.com",
subject: "お問い合わせが届きました" # メール件名
end
end
メールテンプレートを作成する
- ここに記述した内容がメール本文になります。
- メーラークラスのメソッド内で使用したインスタンス変数は、ここで参照できます。
- バックスラッシュを使うことで、改行できます。
- 先述した通り、
config/environments/development.rb
に必要な設定をしていれば、URLヘルパーを使うこともできます。
app/views/notice_mailer/sendmail_contact.text.haml
お問い合わせが届きました。
\
= "会社名: #{@contact.company}"
= "お名前: #{@contact.name}"
= "メールアドレス: #{@contact.email}"
= "電話番号: #{@contact.telephone}"
お問い合わせ内容:
= @contact.message
メーラークラスのメソッドを呼び出す
- 追加しているのは、
NoticeMailer.sendmail_contact(@contact).deliver
の1行です。
app/controllers/contacts_controller.rb
class ContactsController < ApplicationController
def new
@contact = Contact.new
end
def create
@contact = Contact.new(contact_params)
if @contact.save
NoticeMailer.sendmail_contact(@contact).deliver # ここで呼び出している
redirect_to new_contact_url, notice: '問い合わせの送信に成功しました。'
else
render :new
end
end
private
def contact_params
params.require(:contact).permit(:company, :name, :email, :telephone, :message)
end
end
これで一通りの実装が完了しました。実際に動かしてみましょう!
(option)development環境から実際にメール送信する
- letter_opener を使わず、実際にメールを送信してみる場合は、
config/environments/development.rb
を以下のように記述します。 - 今回は、ドメインはGmailのものを設定します。
- Gmailのアプリパスワードというのは、普段Googleのアカウントにログインするために使っているパスワードとは異なりますので、ご注意ください。
config/environments/development.rb
Rails.application.configure do
#...(中略)...
# コメントアウトすることでdevelop環境からもメールを送信する設定になる
# config.action_mailer.raise_delivery_errors = false
# smtpで実際にメール送信させる
config.action_mailer.delivery_method = :smtp
# config.action_mailer.delivery_method = :letter_opener
# メールテンプレートはviewと違ってURLヘルパーを使ってもドメインが取得できず、メール本文にURLを載せられないので、その対策をする
config.action_mailer.default_url_options = {:host => 'localhost:3000'}
config.action_mailer.smtp_settings = {
:enable_starttls_auto => true,
:address => 'smtp.gmail.com',
:port => 587,
:domain => 'gmail.com',
:authentication => :plain,
# 本当に飛ばす場合(letter_openerを使わない場合)は、Gmailのメールアドレスが必要
:user_name => 'aaaaa@gmail.com',
# 本当に飛ばす場合(letter_openerを使わない場合)は、Gmailのアプリパスワードが必要
:password => 'aaaabbbbccccdddd'
}
end
追記:機密情報の記述について
アプリパスワードなどの機密情報の記述について、別記事にまとめましたので、ぜひご覧ください。
(WIP)production環境から実際にメール送信する
- 本番環境については別記事にまとめる予定です。まだ私も実装できていないので…。