Action Mailer Basics
This guide covers sending emails from your Rails application.
After reading this guide, you will know:
- How to generate and edit Action Mailer classes and mailer views.
- How to send attachments and multipart emails.
- How to use Action Mailer callbacks.
- How to configure Action Mailer for your environment.
- How to preview emails and test your Action Mailer classes.
1. What is Action Mailer?
Action Mailer allows you to send emails from your Rails application. It's one ofthe two email related components in the Rails framework. The other isActionMailbox, which deals withreceiving emails.
Action Mailer uses classes (called "mailers") and views to create and configurethe email to send. Mailers are classes that inherit fromActionMailer::Base. Mailer classes are similar to controller classes. Bothhave:
- Instance variables that are accessible in views.
- The ability to use layouts and partials.
- The ability to access a params hash.
- Actions and associated views in
app/views.
2. Creating a Mailer and Views
This section will provide a step-by-step guide to sending email with ActionMailer. Here are the details of each step.
2.1. Generate the Mailer
First, you use the "mailer" generator to create the Mailer related classes:
$bin/railsgenerate mailer Usercreate app/mailers/user_mailer.rbinvoke erbcreate app/views/user_mailerinvoke test_unitcreate test/mailers/user_mailer_test.rbcreate test/mailers/previews/user_mailer_preview.rbLike theUserMailer below, all generated Mailer classes inherit fromApplicationMailer:
# app/mailers/user_mailer.rbclassUserMailer<ApplicationMailerendTheApplicationMailer class inherits fromActionMailer::Base, and can beused to define attributes common to all Mailers:
# app/mailers/application_mailer.rbclassApplicationMailer<ActionMailer::Basedefaultfrom:"from@example.com"layout"mailer"endIf you don't want to use a generator, you can also manually add a file to theapp/mailers directory. Make sure that your class inherits fromApplicationMailer:
# app/mailers/custom_mailer.rbclassCustomMailer<ApplicationMailerend2.2. Edit the Mailer
TheUserMailer inapp/mailers/user_mailer.rb initially doesn't have any methods. So next, we addmethods (aka actions) to the mailer that will send specific emails.
Mailers have methods called "actions" and they use views to structure theircontent, similar to controllers. While a controller generates HTML content tosend back to the client, a Mailer creates a message to be delivered via email.
Let's add a method calledwelcome_email to theUserMailer, that will send anemail to the user's registered email address:
classUserMailer<ApplicationMailerdefaultfrom:"notifications@example.com"defwelcome_email@user=params[:user]@url="http://example.com/login"mail(to:@user.email,subject:"Welcome to My Awesome Site")endendThe method names in mailers do not have to end in_email.
Here is a quick explanation of the Mailer related methods used above:
- The
defaultmethod sets default values for all emails sent fromthismailer. In this case, we use it to set the:fromheader value for allmessages in this class. This can be overridden on a per-email basis. - The
mailmethod creates the actual email message. We use it to specifythe values of headers like:toand:subjectper email.
There is also theheaders method (not used above), which is used tospecify email headers with a hash or by callingheaders[:field_name] = 'value'.
It is possible to specify an action directly while using the generator likethis:
$bin/railsgenerate mailer User welcome_emailThe above will generate theUserMailer with an emptywelcome_email method.
You can also send multiple emails from a single mailer class. It can beconvenient to group related emails together. For example, the aboveUserMailercan have agoodbye_email (and corresponding view) in addition to thewelcome_email.
2.3. Create a Mailer View
Next, for thewelcome_email action, you'll need to create a matching view in afile calledwelcome_email.html.erb in theapp/views/user_mailer/ directory.Here is a sample HTML template that can be used for the welcome email:
<h1>Welcome to example.com,<%=@user.name%></h1><p> You have successfully signed up to example.com, your username is:<%=@user.login%>.<br></p><p> To log in to the site, just follow this link:<%=link_to'login',login_url%>.</p><p>Thanks for joining and have a great day!</p>The above is the content of the<body> tag. It will be embedded in thedefault mailer layout, which contains the<html> tag. SeeMailerlayouts for more.
You can also create a text version of the above email and store it inwelcome_email.text.erb in theapp/views/user_mailer/ directory (notice the.text.erb extension vs. thehtml.erb). Sending both formats is consideredbest practice because, in case of HTML rendering issues, the text version canserve as a reliable fallback. Here is a sample text email:
Welcome to example.com,<%=@user.name%>===============================================You have successfully signed up to example.com,your username is:<%=@user.login%>.To log in to the site, just follow this link:<%=@url%>.Thanks for joining and have a great day!Notice that in both HTML and text email templates you can use the instancevariables@user and@url.
Now, when you call themail method, Action Mailer will detect the twotemplates (text and HTML) and automatically generate amultipart/alternativeemail.
2.4. Call the Mailer
Once you have a mailer class and view set up, the next step is to actually callthe mailer method that renders the email view (i.e. sends the email). Mailerscan be thought of as another way of rendering views. Controller actions render aview to be sent over the HTTP protocol. Mailer actions render a view and send itthrough email protocols instead.
Let's see an example of using theUserMailer to send a welcome email when auser is successfully created.
First, let's create aUser scaffold:
$bin/railsgenerate scaffold user name email login$bin/railsdb:migrateNext, we edit thecreate action in theUserController to send a welcomeemail when a new user is created. We do this by inserting a call toUserMailer.with(user: @user).welcome_email right after the user issuccessfully saved.
We usedeliver_later to enqueue the email to be sent later. Thisway, the controller action will continue without waiting for the email sendingcode to run. Thedeliver_later method is backed byActiveJob.
classUsersController<ApplicationController# ...defcreate@user=User.new(user_params)respond_todo|format|if@user.save# Tell the UserMailer to send a welcome email after saveUserMailer.with(user:@user).welcome_email.deliver_laterformat.html{redirect_touser_url(@user),notice:"User was successfully created."}format.json{render:show,status: :created,location:@user}elseformat.html{render:new,status: :unprocessable_entity}format.json{renderjson:@user.errors,status: :unprocessable_entity}endendend# ...endAny key-value pair passed towith becomes theparams for the Maileraction. For example,with(user: @user, account: @user.account) makesparams[:user] andparams[:account] available in the Mailer action.
With the above mailer, view, and controller set up, if you create a newUser,you can examine the logs to see the welcome email being sent. The log file willshow the text and HTML versions being sent, like this:
[ActiveJob] [ActionMailer::MailDeliveryJob] [ec4b3786-b9fc-4b5e-8153-9153095e1cbf] Delivered mail 6661f55087e34_1380c7eb86934d@Bhumis-MacBook-Pro.local.mail (19.9ms)[ActiveJob] [ActionMailer::MailDeliveryJob] [ec4b3786-b9fc-4b5e-8153-9153095e1cbf] Date: Thu, 06 Jun 2024 12:43:44 -0500From: notifications@example.comTo: test@gmail.comMessage-ID: <6661f55087e34_1380c7eb86934d@Bhumis-MacBook-Pro.local.mail>Subject: Welcome to My Awesome SiteMime-Version: 1.0Content-Type: multipart/alternative; boundary="--==_mimepart_6661f55086194_1380c7eb869259"; charset=UTF-8Content-Transfer-Encoding: 7bit----==_mimepart_6661f55086194_1380c7eb869259Content-Type: text/plain;...----==_mimepart_6661f55086194_1380c7eb869259Content-Type: text/html;...You can also call the mailer from the Rails console and send emails, perhapsuseful as a test before you have a controller action set up. The below will sendthe samewelcome_email as above:
irb>user=User.firstirb>UserMailer.with(user:user).welcome_email.deliver_laterIf you want to send emails right away (from a cronjob for example) you can calldeliver_now:
classSendWeeklySummarydefrunUser.find_eachdo|user|UserMailer.with(user:user).weekly_summary.deliver_nowendendendA method likeweekly_summary fromUserMailer would return anActionMailer::MessageDelivery object, which has the methodsdeliver_nowordeliver_later to send itself now or later. TheActionMailer::MessageDelivery object is a wrapper around aMail::Message. If you want to inspect, alter, or do anything else with theMail::Message object you can access it with themessage method on theActionMailer::MessageDelivery object.
Here is an example of theMessageDelivery object from the Rails consoleexample above:
irb>UserMailer.with(user:user).weekly_summary#<ActionMailer::MailDeliveryJob:0x00007f84cb0367c0 @_halted_callback_hook_called=nil, @_scheduled_at_time=nil, @arguments= ["UserMailer", "welcome_email", "deliver_now", {:params=> {:user=> #<User:0x00007f84c9327198 id: 1, name: "Bhumi", email: "hi@gmail.com", login: "Bhumi", created_at: Thu, 06 Jun 2024 17:43:44.424064000 UTC +00:00, updated_at: Thu, 06 Jun 2024 17:43:44.424064000 UTC +00:00>}, :args=>[]}], @exception_executions={}, @executions=0, @job_id="07747748-59cc-4e88-812a-0d677040cd5a", @priority=nil,3. Multipart Emails and Attachments
Themultipart MIME type represents a document that's comprised of multiple component parts, each of which may have its own individual MIME type (such as thetext/html andtext/plain). Themultipart type encapsulates sending multiple files together in one transaction such as attaching multiple files to an email for example.
3.1. Adding Attachments
You can add an attachment with Action Mailer by passing the file name andcontent to theattachmentsmethod.Action Mailer will automatically guess themime_type, set theencoding, andcreate the attachment.
attachments["filename.jpg"]=File.read("/path/to/filename.jpg")When themail method is triggered, it will send a multipart email with anattachment, properly nested with the top level beingmultipart/mixed and thefirst part being amultipart/alternative containing the plain text and HTMLemail messages.
The other way to send attachments is to specify the file name, MIME-type andencoding headers, and content. Action Mailer will use the settings you pass in.
encoded_content=SpecialEncode(File.read("/path/to/filename.jpg"))attachments["filename.jpg"]={mime_type:"application/gzip",encoding:"SpecialEncoding",content:encoded_content}Action Mailer will automatically Base64 encode an attachment. If you wantsomething different, you can encode your content and pass in the encoded contentas well as the encoding in aHash to theattachments method. If you specifyan encoding, Action Mailer will not try to Base64 encode the attachment.
3.2. Making Inline Attachments
Sometimes, you may want to send an attachment (e.g. image) inline, so it appearswithin the email body.
In order to do this, first, you turn an attachment into an inline attachment bycalling#inline:
defwelcomeattachments.inline["image.jpg"]=File.read("/path/to/image.jpg")endThen in the view, you can referenceattachments as a hash and specify the fileyou want to show inline. You can callurl on the hash and pass the result intotheimage_tagmethod:
<p>Hello there, this is the image you requested:</p><%=image_tagattachments['image.jpg'].url%>Since this is a standard call toimage_tag you can pass in an options hashafter the attachment URL as well:
<p>Hello there, this is our image</p><%=image_tagattachments['image.jpg'].url,alt:'My Photo',class:'photos'%>3.3. Multipart Emails
As demonstrated inCreate a Mailer View, Action Mailerwill automatically send multipart emails if you have different templates for thesame action. For example, if you have aUserMailer withwelcome_email.text.erb andwelcome_email.html.erb inapp/views/user_mailer, Action Mailer will automatically send a multipart emailwith both the HTML and text versions included as separate parts.
TheMail gem has helper methods for making amultipart/alternate email fortext/plain andtext/htmlMIMEtypesand you can manually create any other type of MIME email.
The order of the parts getting inserted is determined by the:parts_order inside of theActionMailer::Base.default method.
Multipart is also used when you send attachments with email.
4. Mailer Views and Layouts
Action Mailer uses view files to specify the content to be sent in emails.Mailer views are located in theapp/views/name_of_mailer_class directory bydefault. Similar to a controller view, the name of the file matches the name ofthe mailer method.
Mailer views are rendered within a layout, similar to controller views. Mailerlayouts are located inapp/views/layouts. The default layout ismailer.html.erb andmailer.text.erb. This section covers various featuresaround mailer views and layouts.
4.1. Configuring Custom View Paths
It is possible to change the default mailer view for your action in variousways, as shown below.
There aretemplate_path andtemplate_name options to themail method:
classUserMailer<ApplicationMailerdefaultfrom:"notifications@example.com"defwelcome_email@user=params[:user]@url="http://example.com/login"mail(to:@user.email,subject:"Welcome to My Awesome Site",template_path:"notifications",template_name:"hello")endendThe above configures themail method to look for a template with the namehello in theapp/views/notifications directory. You can also specify anarray of paths fortemplate_path, and they will be searched in order.
If you need more flexibility, you can also pass a block and render a specifictemplate. You can also render plain text inline without using a template file:
classUserMailer<ApplicationMailerdefaultfrom:"notifications@example.com"defwelcome_email@user=params[:user]@url="http://example.com/login"mail(to:@user.email,subject:"Welcome to My Awesome Site")do|format|format.html{render"another_template"}format.text{renderplain:"hello"}endendendThis will render the templateanother_template.html.erb for the HTML part and"hello" for the text part. Therendermethod is the same one used inside of Action Controller, so you can use all thesame options, such as:plain,:inline, etc.
Lastly, if you need to render a template located outside of the defaultapp/views/mailer_name/ directory, you can apply theprepend_view_path,like so:
classUserMailer<ApplicationMailerprepend_view_path"custom/path/to/mailer/view"# This will try to load "custom/path/to/mailer/view/welcome_email" templatedefwelcome_email# ...endendThere is also anappend_view_path method.
4.2. Generating URLs in Action Mailer Views
In order to add URLs to your mailer, you need to set thehost value to yourapplication's domain first. This is because, unlike controllers, the mailerinstance doesn't have any context about the incoming request.
You can configure the defaulthost across the application inconfig/application.rb:
config.action_mailer.default_url_options={host:"example.com"}Once thehost is configured, it is recommended that email views use the*_url with the full URL, and not the*_path helpers with relative URL. Sinceemail clients do not have web request context,*_path helpers have no base URLto form complete web addresses.
For example, instead of:
<%=link_to'welcome',welcome_path%>Use:
<%=link_to'welcome',welcome_url%>By using the full URL, your links will work correctly in your emails.
4.2.1. Generating URLs withurl_for
Theurl_for helper generates a full URL, by default, in templates.
If you haven't configured the:host option globally, you'll need to pass it tourl_for.
<%=url_for(host:'example.com',controller:'welcome',action:'greeting')%>4.2.2. Generating URLs with Named Routes
Similar to other URLs, you need to use the*_url variant of named routehelpers in emails as well.
You either configure the:host option globally or make sure to pass it to theURL helper:
<%=user_url(@user,host:'example.com')%>4.3. Adding Images in Action Mailer Views
In order to use theimage_tag helper in emails, you need to specify the:asset_host parameter. This is because a mailer instance doesn't have anycontext about the incoming request.
Usually the:asset_host is consistent across the application, so you canconfigure it globally inconfig/application.rb:
config.action_mailer.asset_host="http://example.com"Because we can't infer the protocol from the request, you'll need tospecify a protocol such ashttp:// orhttps:// in the:asset_host config.
Now you can display an image inside your email.
<%=image_tag'image.jpg'%>4.4. Caching Mailer View
You can perform fragment caching in mailer views, similar to application views,using thecache method.
<%cachedo%><%=@company.name%><%end%>And to use this feature, you need to enable it in your application'sconfig/environments/*.rb file:
config.action_mailer.perform_caching=trueFragment caching is also supported in multipart emails. Read more about cachingin theRails caching guide.
4.5. Action Mailer Layouts
Just like controller layouts, you can also have mailer layouts. Mailer layoutsare located inapp/views/layouts. Here is the default layout:
# app/views/layouts/mailer.html.erb<!DOCTYPE html><html><head><metahttp-equiv="Content-Type"content="text/html; charset=utf-8"><style>/* Email styles need to be inline */</style></head><body><%=yield%></body></html>The above layout is in a filemailer.html.erb. The default layout name isspecified in theApplicationMailer, as we saw earlier with the linelayout"mailer" in theGenerate Mailer section. Similar tocontroller layouts, you useyield to render the mailer view inside the layout.
To use a different layout for a given mailer, calllayout:
classUserMailer<ApplicationMailerlayout"awesome"# Use awesome.(html|text).erb as the layoutendTo use a specific layout for a given email, you can pass in alayout:'layout_name' option to the render call inside the format block:
classUserMailer<ApplicationMailerdefwelcome_emailmail(to:params[:user].email)do|format|format.html{renderlayout:"my_layout"}format.textendendendThe above will render the HTML part using themy_layout.html.erb file and thetext part with the usualuser_mailer.text.erb file.
5. Sending Email
5.1. Sending Email to Multiple Recipients
It is possible to send an email to more than one recipient by setting the:tofield to a list of email addresses. The list of emails can be an array or asingle string with the addresses separated by commas.
For example, to inform all admins of a new registration:
classAdminMailer<ApplicationMailerdefaultto:->{Admin.pluck(:email)},from:"notification@example.com"defnew_registration(user)@user=usermail(subject:"New User Signup:#{@user.email}")endendThe same format can be used to add multiple carbon copy (cc) and blind carboncopy (bcc) recipients, by setting the:cc and:bcc keys respectively(similarly to the:to field).
5.2. Sending Email with Name
It's possible to show the name, in addition to the email address, of the personwho receives the email or sends the email.
To show the name of the person when they receive the email, you can useemail_address_with_name method into::
defwelcome_email@user=params[:user]mail(to:email_address_with_name(@user.email,@user.name),subject:"Welcome to My Awesome Site")endThe same method infrom: works to display the name of the sender:
classUserMailer<ApplicationMailerdefaultfrom:email_address_with_name("notification@example.com","Example Company Notifications")endIf the name is blank (nil or empty string), it returns the email address.
5.3. Sending Email with Subject Translation
If you don't pass a subject to the mail method, Action Mailer will try to findit in your translations. See theInternationalizationGuide for more.
5.4. Sending Emails without Template Rendering
There may be cases in which you want to skip the template rendering step andinstead supply the email body as a string. You can achieve this using the:body option. Remember to set the:content_type option, such as setting ittotext/html below. Rails will default totext/plain as the content type.
classUserMailer<ApplicationMailerdefwelcome_emailmail(to:params[:user].email,body:params[:email_body],content_type:"text/html",subject:"Already rendered!")endend5.5. Sending Emails with Dynamic Delivery Options
If you wish to override the default deliveryconfiguration (e.g. SMTP credentials) whiledelivering emails, you can do this usingdelivery_method_options in the maileraction.
classUserMailer<ApplicationMailerdefwelcome_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:"Please see the Terms and Conditions attached",delivery_method_options:delivery_options)endend6. Action Mailer Callbacks
Action Mailer allows for you to specify*_action callbacks to configure the message, and*_deliver callbacks to control the delivery.
Here is a list with all the available Action Mailer callbacks, listedin the order in which they will get called when sending an email:
Callbacks can be specified with a block or a symbol representing a method name in the mailer class, similar to other callbacks (in controllers or models).
Here are some examples of when you may use one of these callbacks with mailers.
6.1.before_action
You can use abefore_action to set instance variables, populate the mailobject with defaults, or insert default headers and attachments.
classInvitationsMailer<ApplicationMailerbefore_action:set_inviter_and_inviteebefore_action{@account=params[:inviter].account}defaultto:->{@invitee.email_address},from:->{common_address(@inviter)},reply_to:->{@inviter.email_address_with_name}defaccount_invitationmailsubject:"#{@inviter.name} invited you to their Basecamp (#{@account.name})"enddefproject_invitation@project=params[:project]@summarizer=ProjectInvitationSummarizer.new(@project.bucket)mailsubject:"#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"endprivatedefset_inviter_and_invitee@inviter=params[:inviter]@invitee=params[:invitee]endend6.2.after_action
You can use anafter_action callback with a similar setup as abefore_actionbut also have access to instance variables that were set in your mailer action.
You can also use anafter_action to override delivery method settings byupdatingmail.delivery_method.settings.
classUserMailer<ApplicationMailerbefore_action{@business,@user=params[:business],params[:user]}after_action:set_delivery_options,:prevent_delivery_to_guests,:set_business_headersdeffeedback_messageenddefcampaign_messageendprivatedefset_delivery_options# You have access to the mail instance,# @business and @user instance variables hereif@business&&@business.has_smtp_settings?mail.delivery_method.settings.merge!(@business.smtp_settings)endenddefprevent_delivery_to_guestsif@user&&@user.guest?mail.perform_deliveries=falseendenddefset_business_headersif@businessheaders["X-SMTPAPI-CATEGORY"]=@business.codeendendend6.3.after_deliver
You could use anafter_deliver to record the delivery of the message. It alsoallows observer/interceptor-like behaviors, but with access to the full mailercontext.
classUserMailer<ApplicationMailerafter_deliver:mark_deliveredbefore_deliver:sandbox_stagingafter_deliver:observe_deliverydeffeedback_message@feedback=params[:feedback]endprivatedefmark_deliveredparams[:feedback].touch(:delivered_at)end# An Interceptor alternative.defsandbox_stagingmessage.to=["sandbox@example.com"]ifRails.env.staging?end# A callback has more context than the comparable Observer example.defobserve_deliveryEmailDelivery.log(message,self.class,action_name,params)endendMailer callbacks abort further processing ifbody is set to a non-nil value.before_deliver can abort withthrow :abort.
7. Action Mailer View Helpers
Action Mailer views have access to most of the same helpers as regular views.
There are also some Action Mailer-specific helper methods available inActionMailer::MailHelper. For example, these allow accessing the mailerinstance from your view withmailer, and accessing themessage asmessage:
<%=stylesheet_link_tagmailer.name.underscore%><h1><%=message.subject%></h1>8. Action Mailer Configuration
This section shows some example configurations for Action Mailer.
For more details on the various configuration options, see theConfiguringRails Applications guide. You canspecify configuration options in environment specific files such asproduction.rb.
8.1. Example Action Mailer Configuration
Here is an example using the:sendmail delivery method, added to aconfig/environments/$RAILS_ENV.rb file:
config.action_mailer.delivery_method=:sendmail# Defaults to:# config.action_mailer.sendmail_settings = {# location: '/usr/sbin/sendmail',# arguments: %w[ -i ]# }config.action_mailer.perform_deliveries=trueconfig.action_mailer.raise_delivery_errors=trueconfig.action_mailer.default_options={from:"no-reply@example.com"}8.2. Action Mailer Configuration for Gmail
Add this to yourconfig/environments/$RAILS_ENV.rb file to send via Gmail:
config.action_mailer.delivery_method=:smtpconfig.action_mailer.smtp_settings={address:"smtp.gmail.com",port:587,domain:"example.com",user_name:Rails.application.credentials.dig(:smtp,:user_name),password:Rails.application.credentials.dig(:smtp,:password),authentication:"plain",enable_starttls:true,open_timeout:5,read_timeout:5}Googleblockssign-ins from apps it deemsless secure. You canchange your Gmail settings to allow theattempts. If your Gmail account has 2-factor authentication enabled, then youwill need to set anapp passwordand use that instead of your regular password.
9. Previewing and Testing Mailers
You can find detailed instructions on how to test your mailers in thetestingguide.
9.1. Previewing Emails
You can preview rendered email templates visually by visiting a special ActionMailer preview URL. To set up a preview forUserMailer, create a class namedUserMailerPreview in thetest/mailers/previews/ directory. To see thepreview ofwelcome_email fromUserMailer, implement a method that has thesame name inUserMailerPreview and callUserMailer.welcome_email:
classUserMailerPreview<ActionMailer::Previewdefwelcome_emailUserMailer.with(user:User.first).welcome_emailendendNow the preview will be available athttp://localhost:3000/rails/mailers/user_mailer/welcome_email.
If you change something in the mailer view atapp/views/user_mailer/welcome_email.html.erb or the mailer itself, the previewwill automatically be updated. A list of previews is also available inhttp://localhost:3000/rails/mailers.
By default, these preview classes live intest/mailers/previews. This can beconfigured using thepreview_paths option. For example, if you want to addlib/mailer_previews to it, you can configure it inconfig/application.rb:
config.action_mailer.preview_paths<<"#{Rails.root}/lib/mailer_previews"9.2. Rescuing Errors
Rescue blocks inside of a mailer method cannot rescue errors that occur outsideof rendering. For example, record deserialization errors in a background job, orerrors from a third-party mail delivery service.
To rescue errors that occur during any part of the mailing process, userescue_from:
classNotifierMailer<ApplicationMailerrescue_fromActiveJob::DeserializationErrordo# ...endrescue_from"SomeThirdPartyService::ApiError"do# ...enddefnotify(recipient)mail(to:recipient,subject:"Notification")endend10. Intercepting and Observing Emails
Action Mailer provides hooks into the Mail observer and interceptor methods.These allow you to register classes that are called during the mail deliverylife cycle of every email sent.
10.1. Intercepting Emails
Interceptors allow you to make modifications to emails before they are handedoff to the delivery agents. An interceptor class must implement the.delivering_email(message) method which will be called before the email issent.
classSandboxEmailInterceptordefself.delivering_email(message)message.to=["sandbox@example.com"]endendThe interceptor needs to be registered using theinterceptors config option.You can do this in an initializer file likeconfig/initializers/mail_interceptors.rb:
Rails.application.configuredoifRails.env.staging?config.action_mailer.interceptors=%w[SandboxEmailInterceptor]endendThe example above uses a custom environment called "staging" for aproduction-like server but for testing purposes. You can readCreating RailsEnvironments for more informationabout custom Rails environments.
10.2. Observing Emails
Observers give you access to the email messageafter it has been sent. Anobserver class must implement the:delivered_email(message) method, which willbe called after the email is sent.
classEmailDeliveryObserverdefself.delivered_email(message)EmailDelivery.log(message)endendSimilar to interceptors, you must register observers using theobserversconfig option. You can do this in an initializer file likeconfig/initializers/mail_observers.rb:
Rails.application.configuredoconfig.action_mailer.observers=%w[EmailDeliveryObserver]end