本章では、アプリケーションでメールの送受信を行うために必要なすべての事項と、Action Mailerのさまざまな内部情報を提供します。また、メーラーのテスト方法についても説明します。
このガイドの内容:
Action Mailerを使うと、アプリケーションのメーラークラスやビューでメールを送信できます。メーラーの動作はコントローラときわめて似通っています。メーラーはActionMailer::Baseを継承し、app/mailersに配置され、app/viewsにあるビューと結び付けられます。
メーラーには以下が含まれます。
app/viewsに現れる)このセクションでは、メーラーとビューの作成方法を手順を追って説明します。
$ bin/rails generate mailer User create app/mailers/user_mailer.rb create app/mailers/application_mailer.rb invoke erb create app/views/user_mailer create app/views/layouts/mailer.text.erb create app/views/layouts/mailer.html.erb invoke test_unit create test/mailers/user_mailer_test.rb create test/mailers/previews/user_mailer_preview.rb
# app/mailers/application_mailer.rb class ApplicationMailer < ActionMailer::Base default from: "from@example.com" layout 'mailer' end
# app/mailers/user_mailer.rb class UserMailer < ApplicationMailer end
上に示したとおり、Railsの他のジェネレータ同様の方法でメーラーを生成できます。
ジェネレータを使いたくない場合は、app/mailersディレクトリ以下にファイルを作成し、ActionMailer::Baseを継承してください。
class MyMailer < ActionMailer::Base end
メーラーはRailsのコントローラと非常に似通っています。メーラーには「アクション」と呼ばれるメソッドがあり、ビューを使ってメールのコンテンツを構成します。コントローラでHTMLなどのメールコンテンツを生成して顧客に送信したい場合、その箇所でメーラーを使って、送信したいメッセージを作成します。
app/mailers/user_mailer.rbには空のメーラーがあります。
class UserMailer < ApplicationMailer end
welcome_emailという名前のメソッドを追加し、ユーザーが登録したメールアドレスにメールを送信できるようにしてみましょう。
class UserMailer < ApplicationMailer default from: 'notifications@example.com' def welcome_email @user = params[:user] @url = 'http://example.com/login' mail(to: @user.email, subject: '私の素敵なサイトへようこそ') end end
上のメソッドで使われている項目について簡単に説明します。利用可能なすべてのオプションについては、「Action Mailerの全メソッド」セクションでユーザー設定可能な属性を参照してください。
default: メーラーから送信するあらゆるメールで使われるデフォルト値のハッシュです。上の例の場合、:fromヘッダーにこのクラスのすべてのメッセージで使う値を1つ設定しています。この値はメールごとに上書きすることもできます。mail: 実際のメールメッセージです。ここでは:toヘッダーと:subjectヘッダーを渡しています。コントローラの場合と同様、メーラーのメソッド内で定義されたすべてのインスタンス変数はそのままビューで使えます。
app/views/user_mailer/ディレクトリでwelcome_email.html.erbというファイルを1つ作成してください。このファイルを、HTMLでフォーマットされたメールテンプレートにします。
<!DOCTYPE html> <html> <head> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' /> </head> <body> <h1><%= @user.name %>様、example.comへようこそ。</h1> <p> example.comへのサインアップが成功しました。 ユーザー名は「<%= @user.login %>」です。<br> </p> <p> このサイトにログインするには、<%= @url %>をクリックしてください。 </p> <p>本サイトにユーザー登録いただきありがとうございます。</p> </body> </html>
続いて、同じ内容のテキストメールも作成しましょう。顧客によってはHTMLフォーマットのメールを受け取りたくない人もいるので、テキストメールも作成しておくとベストです。これを行なうには、app/views/user_mailer/ディレクトリでwelcome_email.text.erbというファイルを以下の内容で作成してください。
<%= @user.name %>様、example.comへようこそ。 =============================================== example.comへのサインアップが成功しました。ユーザー名は「<%= @user.login %>」です。 このサイトにログインするには、<%= @url %>をクリックしてください。 本サイトにユーザー登録いただきありがとうございます。
現在のAction Mailerでは、mailメソッドを呼び出すと2種類のテンプレート (テキストおよびHTML) があるかどうかを探し、multipart/alternative形式のメールを自動生成します。
Railsのメーラーは、ビューのレンダリングと本質的に同じことを行っています。ビューのレンダリングではHTTPプロトコルとして送信されますが、メーラーではメールのプロトコルを経由して送信する点のみが異なります。従って、コントローラでユーザー作成に成功したときに、ビューのレンダリングと同じ要領でメーラーにメール送信を指示できます。
メーラー呼び出しは非常に簡単です。
例として、最初にscaffoldでUserを作成してみましょう。
$ bin/rails generate scaffold user name email login $ bin/rails db:migrate
説明用のユーザーモデルを作成したので、続いてapp/controllers/users_controller.rbを編集し、新規ユーザーの保存成功直後にUserMailerのUserMailer.with(user: @user)を用いてそのユーザーにメールが送信されるようにしましょう。
deliver_laterを使うと、Active Jobによるメールキューにメールを登録できます。これにより、コントローラは送信完了を待たずに処理を続行できます。
class UsersController < ApplicationController # ... # POST /users(または/users.json) def create @user = User.new(user_params) respond_to do |format| if @user.save # 保存後にUserMailerを使ってwelcomeメールを送信 UserMailer.with(user: @user).welcome_email.deliver_later format.html { redirect_to(@user, notice: 'ユーザーが正常に作成されました') } format.json { render json: @user, status: :created, location: @user } else format.html { render action: 'new' } format.json { render json: @user.errors, status: :unprocessable_entity } end end end # ... end
Active Jobはデフォルトでジョブを:asyncアダプタで実行するので、この時点でメールをdeliver_laterで送信できます。
Active Jobのデフォルトのアダプタでは、インプロセスのスレッドプールが送信に用いられます。これは外部のインフラを一切必要としないので、development/test環境に適していますが、ペンディング中のジョブが再起動時に削除されるため、productionには不向きです。永続的なバックエンドが必要な場合は、永続的なバックエンドを用いるActive Jobアダプタ(SidekiqやResqueなど)を使う必要があります。
メールをcronjobなどから今すぐ送信したい場合は、deliver_nowを呼び出すだけで済みます。
class SendWeeklySummary def run User.find_each do |user| UserMailer.with(user: user).weekly_summary.deliver_now end end end
withに渡されるキーの値は、メーラーアクションでは単なるparamsになります。つまり、with(user: @user, account: @user.account)と書けば、メーラーアクションでparams[:user]やparams[:account]を使えるようになります。ちょうどコントローラのparamsと同じ要領です。
このwelcome_emailメソッドはActionMailer::MessageDeliveryオブジェクトを1つ返します。このオブジェクトは、そのメール自身が送信対象であることをdeliver_nowやdeliver_laterに伝えます。ActionMailer::MessageDeliveryオブジェクトは、Mail::Messageをラップしています。内部のMail::Messageオブジェクトの表示や変更などを行いたい場合は、ActionMailer::MessageDeliveryオブジェクトのmessageメソッドにアクセスします。
Action Mailerは、メールのヘッダーや本文のマルチバイト文字を自動的にエンコードします。
別の文字セットを定義したい場合や、事前に手動で別のエンコードを行っておきたい場合などの複雑な事例については、Mailライブラリを参照してください。
以下の3つのメソッドを使えば、ほとんどのメール送信をカバーできます。
headers: メールに追加したいヘッダーを指定します。メールヘッダーのフィールド名と値のペアをハッシュにまとめて渡すことも、headers[:field_name] = 'value'のように呼び出すことも可能です。attachments: メールにファイルを添付します。attachments['file-name.jpg'] = File.read('file-name.jpg')のように記述します。mail: 実際のメール自身を送信します。このメソッドにはヘッダーのハッシュをパラメータとして渡せます。メソッドを呼び出すと、定義しておいたメールテンプレートに応じて、プレーンテキストメールまたはマルチパートメールを送信します。Action Mailerではファイルを簡単に添付できます。
ファイル名とコンテンツを渡すと、Action MailerとMail gemが自動的にmime_typeを推測し、encodingを設定してファイルを添付します。
attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
mailメソッドをトリガーすると、マルチパート形式のメールが1つ送信されます。送信されるメールは、トップレベルがmultipart/mixedで最初のパートがmultipart/alternativeという正しい形式でネストしている、プレーンテキストメールまたはHTMLメールです。
メールに添付されるファイルは自動的にBase64でエンコードされます。他のエンコードを使いたい場合は、事前に好みのエンコードを適用したコンテンツをHashでエンコードしてからattachmentsに渡します。
ヘッダーとコンテンツを指定してファイル名を渡すと、それらの設定がAction MailerとMailによって使われます。
encoded_content = SpecialEncode(File.read('/path/to/filename.jpg')) attachments['filename.jpg'] = { mime_type: 'application/gzip', encoding: 'SpecialEncoding', content: encoded_content }
エンコーディングの種類を指定すると、Mailはコンテンツが既にエンコード済みであると判断し、Base64によるエンコードを行いません。
Action Mailer 3.0はファイルをインライン添付できます。この機能は3.0より前に行われた多数のハックを基に、理想に近づけるべくシンプルな実装にしたものです。
インライン添付を利用することをMailに指示するには、Mailer内のattachmentsメソッドに対して#inlineを呼び出すだけで済みます。
def welcome attachments.inline['image.jpg'] = File.read('/path/to/image.jpg') end
これで、ビューでattachmentsをハッシュとして参照するだけで、表示したい添付ファイルを指定できます。これを行なうには、attachmentsに対してurlを呼び出し、その結果をimage_tagメソッドに渡します。
<p>Hello there, this is our image</p> <%= image_tag attachments['image.jpg'].url %>
これはimage_tagに対する標準的な呼び出しであるため、画像ファイルを扱う場合と同様に、添付URLの後にもオプションのハッシュを渡せます。
<p>こんにちは、以下の写真です。</p> <%= image_tag attachments['image.jpg'].url, alt: 'My Photo', class: 'photos' %>
1つのメールを複数の相手に送信することももちろん可能です(サインアップが新規に行われたことを全管理者に通知するなど)。これを行なうには、メールのリストを:toキーに設定します。メールのリストの形式は、メールアドレスの配列でも、メールアドレスをカンマで区切った文字列でも構いません。
class AdminMailer < ApplicationMailer default to: -> { Admin.pluck(:email) }, from: 'notification@example.com' def new_registration(user) @user = user mail(subject: "New User Signup: #{@user.email}") end end
CC (カーボンコピー) やBCC (ブラインドカーボンコピー) アドレスを指定する場合にも同じ形式を使えます。それぞれ:ccキーと:bccキーを使います。
受信者のメールアドレスをメールにそのまま表示するのではなく、受信者の名前で表示したいことがあります。これは以下のようにemail_address_with_nameメソッドで行なえます。
def welcome_email @user = params[:user] mail( to: email_address_with_name(@user.email, @user.name), subject: '私の素敵なサイトへようこそ' ) end
同じ要領で、送信者名も指定できます。
class UserMailer < ApplicationMailer default from: email_address_with_name('notification@example.com', '会社からのお知らせの例') end
名前が空文字列の場合は、メールアドレスのみを返します。
メーラーのビューはapp/views/name_of_mailer_classディレクトリに置かれます。個別のメーラービューは、その名前がメーラーメソッドと同じになるので、クラスから認識できます。先の例の場合、welcome_emailメソッドで使うメーラービューは、HTML版ではapp/views/user_mailer/welcome_email.html.erbが使われ、プレーンテキストではwelcome_email.text.erbが使われます。
アクションで使うデフォルトのメーラービューを変更するには、たとえば以下のようにします。
class UserMailer < ApplicationMailer default from: 'notifications@example.com' def welcome_email @user = params[:user] @url = 'http://example.com/login' mail(to: @user.email, subject: '私の素敵なサイトへようこそ', template_path: 'notifications', template_name: 'another') end end
上のコードは、app/views/notificationsディレクトリ以下にあるanotherという名前のテンプレートを探索します。template_pathにはパスの配列も指定できます。この場合探索は配列順に沿って行われます。
より柔軟な方法を使いたい場合は、ブロックを渡して特定のテンプレートをレンダリングする方法や、テンプレートを使わずにインラインまたはテキストでレンダリングする方法も利用できます。
class UserMailer < ApplicationMailer default from: 'notifications@example.com' def welcome_email @user = params[:user] @url = 'http://example.com/login' mail(to: @user.email, subject: '私の素敵なサイトへようこそ') do |format| format.html { render 'another_template' } format.text { render plain: 'Render text' } end end end
上のコードは、HTMLの部分を'another_template.html.erb'テンプレートでレンダリングし、テキスト部分をプレーンテキストでレンダリングしています。レンダリングのコマンドはAction Controllerで使われているものと同じなので、:text、:inlineなどのオプションもすべて同様に利用できます。
デフォルトのapp/views/mailer_name/ディレクトリ以外の場所にあるテンプレートでレンダリングしたい場合は、以下のようにprepend_view_pathを適用します。
class UserMailer < ApplicationMailer prepend_view_path "custom/path/to/mailer/view" # "custom/path/to/mailer/view/welcome_email" テンプレートの読み出しを試みる def welcome_email # ... end end
またはappend_view_pathメソッドの利用を検討してもよいでしょう。
cacheメソッドを用いるアプリケーションビューと同じように、メーラービューでもフラグメントキャッシュを利用できます。
<% cache do %> <%= @company.name %> <% end %>
この機能を使うには、アプリケーションで以下の設定が必要です。
config.action_mailer.perform_caching = true
フラグメントキャッシュはメールがマルチパートの場合にもサポートされています。詳しくはRails のキャッシュ機構ガイドを参照してください。
メーラーのレイアウトも、コントローラのビューと同様の方法で設定できます。メーラーで使うレイアウト名はメーラーと同じ名前にする必要があります。たとえば、user_mailer.html.erbやuser_mailer.text.erbというレイアウトは自動的にメーラーでレイアウトとして認識されます。
別のレイアウトファイルを明示的に指定したい場合は、メーラーでlayoutを呼び出します。
class UserMailer < ApplicationMailer layout 'awesome' # awesome.(html|text).erbをレイアウトとして使う end
レイアウト内のビューは、コントローラのビューと同様にyieldでレンダリングできます。
formatブロック内のrenderメソッド呼び出しにlayout: 'layout_name'オプションを渡すと、フォーマットごとに異なるレイアウトも指定できます。
class UserMailer < ApplicationMailer def welcome_email mail(to: params[:user].email) do |format| format.html { render layout: 'my_layout' } format.text end end end
上のコードは、HTMLの部分についてはmy_layout.html.erbレイアウトファイルを明示的に用いてレンダリングし、テキストの部分については通常のuser_mailer.text.erbがあればそれを使ってレンダリングします。
Action Mailerのプレビュー機能は、レンダリング用のURLを開くことでメールの外観を確認する方法を提供します。上の例のUserMailerクラスは、プレビューではUserMailerPreviewという名前にしてtest/mailers/previews/user_mailer_preview.rbに配置すべきです。welcome_emailのプレビューを表示するには、同じ名前のメソッドを実装してUserMailer.welcome_emailを呼び出します。
class UserMailerPreview < ActionMailer::Preview def welcome_email UserMailer.with(user: User.first).welcome_email end end
これで、http://localhost:3000/rails/mailers/user_mailer/welcome_emailにアクセスしてプレビューを表示できます。
app/views/user_mailer/welcome_email.html.erbやメーラー自身に何らかの変更を加えると、自動的に再読み込みしてレンダリングされるので、スタイル変更を画面ですぐ確認できます。利用可能なプレビューのリストはhttp://localhost:3000/rails/mailersで表示できます。
これらのプレビュー用クラスは、デフォルトでtest/mailers/previewsに配置されます。このパスはpreview_pathオプションで設定できます。たとえばlib/mailer_previewsに変更したい場合はconfig/application.rbに以下の設定を追加します。
config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
メーラーのインスタンスは、サーバーが受信するHTTPリクエストのコンテキストと無関係である点がコントローラと異なります。アプリケーションのホスト情報をメーラー内で使いたい場合は:hostパラメータを明示的に指定します。
通常、:hostに指定する値はそのアプリケーション内で共通なので、config/application.rbに以下の記述を追加してグローバルに利用できるようにします。
config.action_mailer.default_url_options = { host: 'example.com' }
*_pathヘルパーは、この動作の性質上メール内では一切利用できない点にご注意ください。メールでURLが必要な場合は、*_urlヘルパーをお使いください。
<%= link_to 'ようこそ', welcome_path %>
上のコードの代わりに、以下のコードを使う必要があります。
<%= link_to 'ようこそ', welcome_url %>
これでフルパスのURLが引用され、メールのURLが正常に機能するようになります。
url_forでURLを生成するテンプレートでurl_forを用いて生成されるURLは、デフォルトでフルパスになります。
:hostオプションをグローバルに設定していない場合は、url_forに:hostオプションを明示的に渡す必要があることにご注意ください。
<%= url_for(host: 'example.com', controller: 'welcome', action: 'greeting') %>
メールクライアントはWebサーバーのコンテキストから切り離されているので、メールに記載するパスではWebのアドレスのベースURLは補完されません。従って、名前付きルーティングヘルパーについても*_pathではなく常に*_urlを使う必要があります。
:hostオプションをグローバルに設定していない場合は、「*_url」ヘルパーに:hostオプションを明示的に渡す必要があることにご注意ください。
<%= user_url(@user, host: 'example.com') %>
GET以外のリンクが機能するにはrails-ujsまたはjQuery UJSが必須ですが、これらはメーラーテンプレートでは機能しません(通常のGETリクエストが出力されます)。
コントローラの場合と異なり、メーラーのインスタンスには受け取ったリクエストのコンテキストが一切含まれません。このため、:asset_hostパラメータを自分で指定する必要があります。
:asset_hostが多くの場合アプリケーション全体で一貫しているのと同様、config/application.rbでグローバルな設定を行えます。
config.action_mailer.asset_host = 'http://example.com'
これで、以下のようにメール内で画像を表示できます。
<%= image_tag 'image.jpg' %>
あるアクションに複数の異なるテンプレートがあると、Action Mailerによって自動的にマルチパート形式のメールが送信されます。UserMailerを例にとって説明します。app/views/user_mailerディレクトリにwelcome_email.text.erbとwelcome_email.html.erbというテンプレートがあると、Action MailerはそれぞれのテンプレートからHTMLメールとテキストメールを生成し、マルチパート形式のメールとして1つにまとめて自動的に送信します。
マルチパートメールに挿入されるパートの順序は、ActionMailer::Base.defaultメソッドの:parts_orderによって決まります。
SMTP認証情報などのデフォルトの配信オプションをメール配信時に上書きしたい場合、メーラーのアクションでdelivery_method_optionsを使って変更できます。
class UserMailer < ApplicationMailer def welcome_email @user = params[:user] @url = user_url(@user) delivery_options = { user_name: params[:company].smtp_user, password: params[:company].smtp_password, address: params[:company].smtp_host } mail(to: @user.email, subject: "添付の利用規約を参照してください", delivery_method_options: delivery_options) end end
メール送信時にテンプレートのレンダリングをスキップしてメール本文を単なる文字列にしたい場合は、:bodyオプションを使えます。このオプションを使う場合は、必ず:content_typeオプションも指定してください。指定がない場合はデフォルトのtext/plainが適用されます。
class UserMailer < ApplicationMailer def welcome_email mail(to: params[:user].email, body: params[:email_body], content_type: "text/html", subject: "レンダリング完了") end end
Action Mailerでは、before_action、after_action、around_actionというコールバックを指定できます。
コントローラと同様、メーラークラスのメソッドにもフィルタ付きのブロックまたはシンボルを渡せます。
before_actionコールバックを使うと、メールオブジェクトにデフォルト値を渡したり、デフォルトのヘッダや添付ファイルを挿入したりできるようになります。
class InvitationsMailer < ApplicationMailer before_action :set_inviter_and_invitee before_action { @account = params[:inviter].account } default to: -> { @invitee.email_address }, from: -> { common_address(@inviter) }, reply_to: -> { @inviter.email_address_with_name } def account_invitation mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})" end def project_invitation @project = params[:project] @summarizer = ProjectInvitationSummarizer.new(@project.bucket) mail subject: "#{@inviter.name.familiar} をBasecampのプロジェクトに追加しました (#{@account.name})" end private def set_inviter_and_invitee @inviter = params[:inviter] @invitee = params[:invitee] end end
after_actionコールバックもbefore_actionと同様のセットアップを行えますが、メーラーのアクション内のインスタンス変数を使います。
after_actionコールバックは、mail.delivery_method.settings設定を更新して配信メソッドを上書きするときにも利用できます。
class UserMailer < ApplicationMailer before_action { @business, @user = params[:business], params[:user] } after_action :set_delivery_options, :prevent_delivery_to_guests, :set_business_headers def feedback_message end def campaign_message end private def set_delivery_options # ここではメールのインスタンスや # @businessや@userインスタンス変数にアクセスできる if @business && @business.has_smtp_settings? mail.delivery_method.settings.merge!(@business.smtp_settings) end end def prevent_delivery_to_guests if @user && @user.guest? mail.perform_deliveries = false end end def set_business_headers if @business headers["X-SMTPAPI-CATEGORY"] = @business.code end end end
Action MailerはAbstractControllerを継承しているので、Action Controllerと同様に一般的なヘルパーメソッドを使えます。
Action Mailer固有のヘルパーメソッドはActionMailer::MailHelperで利用できます。たとえば、mailerを用いてビューからメーラーインスタンスにアクセスすることも、messageでメッセージにアクセスすることも可能です。
<%= stylesheet_link_tag mailer.name.underscore %> <h1><%= message.subject %></h1>
以下の設定オプションは、environment.rbやproduction.rbなどの環境設定ファイルのいずれかで利用するのが最適です。
| 設定 | 説明 |
|---|---|
logger |
可能であればメール送受信に関する情報を生成します。nilを指定するとログ出力を行わなくなります。Ruby自身のLoggerロガーおよびLog4rロガーのどちらとも互換性があります。 |
smtp_settings |
:smtpの配信メソッドの詳細設定を行います。
|
sendmail_settings |
:sendmailの配信オプションを上書きします。
|
raise_delivery_errors |
メール配信に失敗した場合にエラーを発生するかどうかを指定します。このオプションは、外部のメールサーバーが即時配信を行っている場合にのみ機能します。 |
delivery_method |
配信方法を指定します。以下の配信方法を指定可能です。
|
perform_deliveries |
Mailのメッセージにdeliverメソッドを実行したときに実際にメール配信を行なうかどうかを指定します。デフォルトでは配信が行われます。機能テストなどで配信を一時的にオフにしたい場合に便利です。 |
deliveries |
delivery_method :testを用いてAction Mailerから送信されたメールの配列を保持します。単体テストおよび機能テストで最も便利です。 |
delivery_job |
deliver_laterで使われるジョブクラス。デフォルトはActionMailer::MailDeliveryJob。 |
deliver_later_queue_name |
deliver_laterで使われるキュー名。 |
default_options |
mailメソッドオプション (:from、:reply_toなど)のデフォルト値を設定します。 |
設定オプションの完全な説明については「Rails アプリケーションを設定する」ガイドのAction Mailerを設定するを参照してください。
適切なconfig/environments/$RAILS_ENV.rbファイルに追加する設定の例を以下に示します。
config.action_mailer.delivery_method = :sendmail # デフォルトは以下: # config.action_mailer.sendmail_settings = { # location: '/usr/sbin/sendmail', # arguments: '-i' # } config.action_mailer.perform_deliveries = true config.action_mailer.raise_delivery_errors = true config.action_mailer.default_options = {from: 'no-reply@example.com'}
Action MailerはMail gemを利用して同様の設定を受け取れます。Gmailで送信するには、config/environments/$環境名.rbファイルに以下の設定を追加します。
config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'example.com', user_name: '<ユーザー名>', password: '<パスワード>', authentication: 'plain', enable_starttls_auto: true, open_timeout: 5, read_timeout: 5 }
Googleは2014年7月15日より同社のセキュリティ対策を引き上げ、「安全性が低い」とみなされたアプリケーションからの試行をブロックするようになりました。 この試行を許可するには、ここでGmailの設定を変更できます。利用するGmailアカウントで2要素認証が有効になっている場合は、アプリケーションのパスワードを設定して通常のパスワードの代わりに使う必要があります。
メーラーのテスト方法の詳細についてはテスティングガイドのメーラーをテストするを参照してください。
インターセプタを使うと、メールを配信エージェントに渡す前にメールを加工できます。インターセプタクラスは以下のように、メールが送信される前に呼び出される::delivering_email(message)メソッドを実装しなければなりません。
class SandboxEmailInterceptor def self.delivering_email(message) message.to = ['sandbox@example.com'] end end
インターセプタを動かす前に、interceptors設定オプションを用いてインターセプタを登録する必要があります。これを行うには、config/initializers/mail_interceptors.rbなどのイニシャライズファイルを作成します。
Rails.application.configure do if Rails.env.staging? config.action_mailer.interceptors = %w[SandboxEmailInterceptor] end end
上の例では"staging"というカスタマイズした環境を使っています。これはproduction環境に準じた状態でテストを行うための環境です。Railsのカスタム環境についてはRails環境を作成するを参照してください。
オブザーバーを使うと、メールが送信された後でメールのメッセージにアクセスできるようになります。オブザーバークラスは以下のように、メール送信後に呼び出される:delivered_email(message)メソッドを実装しなければなりません。
class EmailDeliveryObserver def self.delivered_email(message) EmailDelivery.log(message) end end
インターセプタのときと同様、observers設定オプションを用いてオブザーバーを登録しなければなりません。これを行うには、config/initializers/mail_observers.rbなどのイニシャライズファイルを作成します。
Rails.application.configure do config.action_mailer.observers = %w[EmailDeliveryObserver] end
Railsガイドは GitHub の yasslab/railsguides.jp で管理・公開されております。本ガイドを読んで気になる文章や間違ったコードを見かけたら、気軽に Pull Request を出して頂けると嬉しいです。Pull Request の送り方については GitHub の README をご参照ください。
原著における間違いを見つけたら『Rails のドキュメントに貢献する』を参考にしながらぜひ Rails コミュニティに貢献してみてください 🛠💨✨
本ガイドの品質向上に向けて、皆さまのご協力が得られれば嬉しいです。
Railsガイド運営チーム (@RailsGuidesJP)
Railsガイドは下記の協賛企業から継続的な支援を受けています。支援・協賛にご興味あれば協賛プランからお問い合わせいただけると嬉しいです。