Help us understand the problem. What is going on with this article?

Railsでメール送信機能を実装する手順を結構丁寧に(development環境編)

More than 1 year has passed since last update.

次からもっとスムースにできるように、ここに執筆します。

前提

  • バージョンは 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環境から実際にメール送信する

  • 本番環境については別記事にまとめる予定です。まだ私も実装できていないので…。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした