action_mailer_basics.md 25.3 KB
Newer Older
1 2
Action Mailer Basics
====================
3

F
Fiona Tay 已提交
4
This guide provides you with all you need to get started in sending and
5 6
receiving emails from and to your application, and many internals of Action
Mailer. It also covers how to test your mailers.
7

8 9
After reading this guide, you will know:

10 11 12 13
* How to send and receive email within a Rails application.
* How to generate and edit an Action Mailer class and mailer view.
* How to configure Action Mailer for your environment.
* How to test your Action Mailer classes.
14

15
--------------------------------------------------------------------------------
16

17 18
Introduction
------------
19

20 21 22 23
Action Mailer allows you to send emails from your application using mailer classes
and views. Mailers work very similarly to controllers. They inherit from
`ActionMailer::Base` and live in `app/mailers`, and they have associated views
that appear in `app/views`.
24

25 26
Sending Emails
--------------
27

28 29
This section will provide a step-by-step guide to creating a mailer and its
views.
30

31
### Walkthrough to Generating a Mailer
32

33
#### Create the Mailer
34

P
Prem Sichanugrist 已提交
35
```bash
36
$ bin/rails generate mailer UserMailer
37 38 39 40
create  app/mailers/user_mailer.rb
invoke  erb
create    app/views/user_mailer
invoke  test_unit
M
Mike Moore 已提交
41
create    test/mailers/user_mailer_test.rb
42
```
43

44 45 46 47 48 49 50 51 52 53 54
As you can see, you can generate mailers just like you use other generators with
Rails. Mailers are conceptually similar to controllers, and so we get a mailer,
a directory for views, and a test.

If you didn't want to use a generator, you could create your own file inside of
app/mailers, just make sure that it inherits from `ActionMailer::Base`:

```ruby
class MyMailer < ActionMailer::Base
end
```
55

56
#### Edit the Mailer
57

58 59 60 61 62
Mailers are very similar to Rails controllers. They also have methods called
"actions" and use views to structure the content. Where a controller generates
content like HTML to send back to the client, a Mailer creates a message to be
delivered via email.

63
`app/mailers/user_mailer.rb` contains an empty mailer:
64

65
```ruby
66
class UserMailer < ActionMailer::Base
67
  default from: 'from@example.com'
68
end
69
```
70

71 72
Let's add a method called `welcome_email`, that will send an email to the user's
registered email address:
73

74
```ruby
75
class UserMailer < ActionMailer::Base
76
  default from: 'notifications@example.com'
77

78
  def welcome_email(user)
79
    @user = user
80
    @url  = 'http://example.com/login'
81
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
82 83
  end
end
84
```
85

86 87 88
Here is a quick explanation of the items presented in the preceding method. For
a full list of all available options, please have a look further down at the
Complete List of Action Mailer user-settable attributes section.
89

90 91 92 93 94
* `default Hash` - This is a hash of default values for any email you send from
this mailer. In this case we are setting the `:from` header to a value for all
messages in this class. This can be overridden on a per-email basis.
* `mail` - The actual email message, we are passing the `:to` and `:subject`
headers in.
95

96 97
Just like controllers, any instance variables we define in the method become
available for use in the views.
98

99
#### Create a Mailer View
100

101 102
Create a file called `welcome_email.html.erb` in `app/views/user_mailer/`. This
will be the template used for the email, formatted in HTML:
103

104
```html+erb
105
<!DOCTYPE html>
106 107
<html>
  <head>
108
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
109 110
  </head>
  <body>
111
    <h1>Welcome to example.com, <%= @user.name %></h1>
112
    <p>
113
      You have successfully signed up to example.com,
114
      your username is: <%= @user.login %>.<br>
115 116
    </p>
    <p>
117
      To login to the site, just follow this link: <%= @url %>.
118 119 120 121
    </p>
    <p>Thanks for joining and have a great day!</p>
  </body>
</html>
122
```
123

124 125 126
Let's also make a text part for this email. Not all clients prefer HTML emails,
and so sending both is best practice. To do this, create a file called
`welcome_email.text.erb` in `app/views/user_mailer/`:
127

128
```erb
129 130 131
Welcome to example.com, <%= @user.name %>
===============================================

132 133
You have successfully signed up to example.com,
your username is: <%= @user.login %>.
134 135 136 137

To login to the site, just follow this link: <%= @url %>.

Thanks for joining and have a great day!
138
```
139

140 141
When you call the `mail` method now, Action Mailer will detect the two templates
(text and HTML) and automatically generate a `multipart/alternative` email.
P
Pratik Naik 已提交
142

143
#### Calling the Mailer
144

145 146
Mailers are really just another way to render a view. Instead of rendering a
view and sending out the HTTP protocol, they are just sending it out through the
147
email protocols instead. Due to this, it makes sense to just have your
148
controller tell the Mailer to send an email when a user is successfully created.
149

150
Setting this up is painfully simple.
151

152
First, let's create a simple `User` scaffold:
153

P
Prem Sichanugrist 已提交
154
```bash
155 156
$ bin/rails generate scaffold user name email login
$ bin/rake db:migrate
157
```
158

159
Now that we have a user model to play with, we will just edit the
160
`app/controllers/users_controller.rb` make it instruct the `UserMailer` to deliver
161
an email to the newly created user by editing the create action and inserting a
162 163 164 165
call to `UserMailer.welcome_email` right after the user is successfully saved.

Action Mailer is nicely integrated with Active Job so you can send emails outside
of the request-response cycle, so the user doesn't have to wait on it:
166

167
```ruby
168 169
class UsersController < ApplicationController
  # POST /users
170
  # POST /users.json
171 172 173 174 175
  def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
176
        # Tell the UserMailer to send a welcome email after save
177
        UserMailer.welcome_email(@user).deliver_later
178

179 180
        format.html { redirect_to(@user, notice: 'User was successfully created.') }
        format.json { render json: @user, status: :created, location: @user }
181
      else
182 183
        format.html { render action: 'new' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
184 185
      end
    end
186
  end
187
end
188
```
189

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
NOTE: By default Active Job is configured to execute the job `:inline`. So you can
use `deliver_later` now to send the emails and when you decide to start sending the
email from a background job you'll just have to setup Active Job to use a queueing
backend (Sidekiq, Resque, etc).

If you want to send the emails right away (from a cronjob for example) just
call `deliver_now`:

```ruby
class SendWeeklySummary
  def run
    User.find_each do |user|
      UserMailer.weekly_summary(user).deliver_now
    end
  end
end
```

The method `welcome_email` returns a `ActionMailer::MessageDelivery` object which
can then just be told `deliver_now` or `deliver_later` to send itself out. The
`ActionMailer::MessageDelivery` object is just a wrapper around a `Mail::Message`. If
you want to inspect, alter or do anything else with the `Mail::Message` object you can
access it with the `message` method on the `ActionMailer::MessageDelivery` object.
213

214
### Auto encoding header values
215

216 217
Action Mailer handles the auto encoding of multibyte characters inside of
headers and bodies.
218

219 220 221
For more complex examples such as defining alternate character sets or
self-encoding text first, please refer to the
[Mail](https://github.com/mikel/mail) library.
222

223
### Complete List of Action Mailer Methods
224

225 226
There are just three methods that you need to send pretty much any email
message:
227

228 229 230 231 232 233 234 235
* `headers` - Specifies any header on the email you want. You can pass a hash of
  header field names and value pairs, or you can call `headers[:field_name] =
  'value'`.
* `attachments` - Allows you to add attachments to your email. For example,
  `attachments['file-name.jpg'] = File.read('file-name.jpg')`.
* `mail` - Sends the actual email itself. You can pass in headers as a hash to
  the mail method as a parameter, mail will then create an email, either plain
  text, or multipart, depending on what email templates you have defined.
236

237
#### Adding Attachments
238

239
Action Mailer makes it very easy to add attachments.
240

241 242 243
* Pass the file name and content and Action Mailer and the
  [Mail gem](https://github.com/mikel/mail) will automatically guess the
  mime_type, set the encoding and create the attachment.
244

245 246 247
    ```ruby
    attachments['filename.jpg'] = File.read('/path/to/filename.jpg')
    ```
248

249 250 251 252 253
  When the `mail` method will be triggered, it will send a multipart email with
  an attachment, properly nested with the top level being `multipart/mixed` and
  the first part being a `multipart/alternative` containing the plain text and
  HTML email messages.

254 255 256
NOTE: Mail will automatically Base64 encode an attachment. If you want something
different, encode your content and pass in the encoded content and encoding in a
`Hash` to the `attachments` method.
257

258 259
* Pass the file name and specify headers and content and Action Mailer and Mail
  will use the settings you pass in.
260

261 262
    ```ruby
    encoded_content = SpecialEncode(File.read('/path/to/filename.jpg'))
263 264 265 266 267
    attachments['filename.jpg'] = {
      mime_type: 'application/x-gzip',
      encoding: 'SpecialEncoding',
      content: encoded_content
    }
268
    ```
269

270 271
NOTE: If you specify an encoding, Mail will assume that your content is already
encoded and not try to Base64 encode it.
272

273
#### Making Inline Attachments
274

275
Action Mailer 3.0 makes inline attachments, which involved a lot of hacking in pre 3.0 versions, much simpler and trivial as they should be.
276

277
* First, to tell Mail to turn an attachment into an inline attachment, you just call `#inline` on the attachments method within your Mailer:
278

279 280 281 282 283
    ```ruby
    def welcome
      attachments.inline['image.jpg'] = File.read('/path/to/image.jpg')
    end
    ```
284

285 286 287
* Then in your view, you can just reference `attachments` as a hash and specify
  which attachment you want to show, calling `url` on it and then passing the
  result into the `image_tag` method:
288

289 290
    ```html+erb
    <p>Hello there, this is our image</p>
291

292 293
    <%= image_tag attachments['image.jpg'].url %>
    ```
294

295 296
* As this is a standard call to `image_tag` you can pass in an options hash
  after the attachment URL as you could for any other image:
297

298 299
    ```html+erb
    <p>Hello there, this is our image</p>
300

301 302
    <%= image_tag attachments['image.jpg'].url, alt: 'My Photo',
                                                class: 'photos' %>
303
    ```
304

305
#### Sending Email To Multiple Recipients
306

307 308 309 310
It is possible to send email to one or more recipients in one email (e.g.,
informing all admins of a new signup) by setting the list of emails to the `:to`
key. The list of emails can be an array of email addresses or a single string
with the addresses separated by commas.
311

312
```ruby
313
class AdminMailer < ActionMailer::Base
314 315
  default to: Proc.new { Admin.pluck(:email) },
          from: 'notification@example.com'
V
Vijay Dev 已提交
316

317 318
  def new_registration(user)
    @user = user
319
    mail(subject: "New User Signup: #{@user.email}")
320
  end
321
end
322
```
323

324 325
The same format can be used to set carbon copy (Cc:) and blind carbon copy
(Bcc:) recipients, by using the `:cc` and `:bcc` keys respectively.
326

327
#### Sending Email With Name
328

329 330
Sometimes you wish to show the name of the person instead of just their email
address when they receive the email. The trick to doing that is to format the
331
email address in the format `"Full Name <email>"`.
332

333
```ruby
334 335
def welcome_email(user)
  @user = user
336
  email_with_name = %("#{@user.name}" <#{@user.email}>)
337
  mail(to: email_with_name, subject: 'Welcome to My Awesome Site')
338
end
339
```
340

341
### Mailer Views
342

343 344 345 346 347
Mailer views are located in the `app/views/name_of_mailer_class` directory. The
specific mailer view is known to the class because its name is the same as the
mailer method. In our example from above, our mailer view for the
`welcome_email` method will be in `app/views/user_mailer/welcome_email.html.erb`
for the HTML version and `welcome_email.text.erb` for the plain text version.
348 349 350

To change the default mailer view for your action you do something like:

351
```ruby
352
class UserMailer < ActionMailer::Base
353
  default from: 'notifications@example.com'
354 355 356

  def welcome_email(user)
    @user = user
357
    @url  = 'http://example.com/login'
358
    mail(to: @user.email,
359 360 361
         subject: 'Welcome to My Awesome Site',
         template_path: 'notifications',
         template_name: 'another')
362 363
  end
end
364
```
365

366 367 368
In this case it will look for templates at `app/views/notifications` with name
`another`.  You can also specify an array of paths for `template_path`, and they
will be searched in order.
369

370 371
If you want more flexibility you can also pass a block and render specific
templates or even render inline or text without using a template file:
372

373
```ruby
374
class UserMailer < ActionMailer::Base
375
  default from: 'notifications@example.com'
376

377
  def welcome_email(user)
378
    @user = user
379
    @url  = 'http://example.com/login'
380
    mail(to: @user.email,
381
         subject: 'Welcome to My Awesome Site') do |format|
382
      format.html { render 'another_template' }
383
      format.text { render text: 'Render text' }
384
    end
P
Pratik Naik 已提交
385
  end
386
end
387
```
388

389 390 391 392
This will render the template 'another_template.html.erb' for the HTML part and
use the rendered text for the text part. The render command is the same one used
inside of Action Controller, so you can use all the same options, such as
`:text`, `:inline` etc.
393

394
### Action Mailer Layouts
395

396 397 398 399
Just like controller views, you can also have mailer layouts. The layout name
needs to be the same as your mailer, such as `user_mailer.html.erb` and
`user_mailer.text.erb` to be automatically recognized by your mailer as a
layout.
400

401
In order to use a different file, call `layout` in your mailer:
402

403
```ruby
404
class UserMailer < ActionMailer::Base
405
  layout 'awesome' # use awesome.(html|text).erb as the layout
406
end
407
```
408

409 410
Just like with controller views, use `yield` to render the view inside the
layout.
411

412
You can also pass in a `layout: 'layout_name'` option to the render call inside
413
the format block to specify different layouts for different formats:
414

415
```ruby
416 417
class UserMailer < ActionMailer::Base
  def welcome_email(user)
418 419
    mail(to: user.email) do |format|
      format.html { render layout: 'my_layout' }
420 421 422 423
      format.text
    end
  end
end
424
```
425

426 427
Will render the HTML part using the `my_layout.html.erb` file and the text part
with the usual `user_mailer.text.erb` file if it exists.
428

429
### Generating URLs in Action Mailer Views
430

431 432 433 434 435 436 437 438 439 440
Unlike controllers, the mailer instance doesn't have any context about the
incoming request so you'll need to provide the `:host` parameter yourself.

As the `:host` usually is consistent across the application you can configure it
globally in `config/application.rb`:

```ruby
config.action_mailer.default_url_options = { host: 'example.com' }
```

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
Because of this behavior you cannot use any of the `*_path` helpers inside of
an email. Instead you will need to use the associated `*_url` helper. For example
instead of using

```
<%= link_to 'welcome', welcome_path %>
```

You will need to use:

```
<%= link_to 'welcome', welcome_url %>
```

By using the full URL, your links will now work in your emails.

457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
#### generating URLs with `url_for`

You need to pass the `only_path: false` option when using `url_for`. This will
ensure that absolute URLs are generated because the `url_for` view helper will,
by default, generate relative URLs when a `:host` option isn't explicitly
provided.

```erb
<%= url_for(controller: 'welcome',
            action: 'greeting',
            only_path: false) %>
```

If you did not configure the `:host` option globally make sure to pass it to
`url_for`.
472

473

474
```erb
475 476 477
<%= url_for(host: 'example.com',
            controller: 'welcome',
            action: 'greeting') %>
478
```
479

480 481
NOTE: When you explicitly pass the `:host` Rails will always generate absolute
URLs, so there is no need to pass `only_path: false`.
482

483
#### generating URLs with named routes
484

485 486 487
Email clients have no web context and so paths have no base URL to form complete
web addresses. Thus, you should always use the "_url" variant of named route
helpers.
488

489 490
If you did not configure the `:host` option globally make sure to pass it to the
url helper.
491

492 493
```erb
<%= user_url(@user, host: 'example.com') %>
494
```
495

496
### Sending Multipart Emails
497

498 499 500 501 502
Action Mailer will automatically send multipart emails if you have different
templates for the same action. So, for our UserMailer example, if you have
`welcome_email.text.erb` and `welcome_email.html.erb` in
`app/views/user_mailer`, Action Mailer will automatically send a multipart email
with the HTML and text versions setup as different parts.
503

504 505
The order of the parts getting inserted is determined by the `:parts_order`
inside of the `ActionMailer::Base.default` method.
506

507
### Sending Emails with Dynamic Delivery Options
508

509 510 511
If you wish to override the default delivery options (e.g. SMTP credentials)
while delivering emails, you can do this using `delivery_method_options` in the
mailer action.
512

513
```ruby
514
class UserMailer < ActionMailer::Base
V
Vijay Dev 已提交
515
  def welcome_email(user, company)
516 517
    @user = user
    @url  = user_url(@user)
518 519 520 521 522 523
    delivery_options = { user_name: company.smtp_user,
                         password: company.smtp_password,
                         address: company.smtp_host }
    mail(to: @user.email,
         subject: "Please see the Terms and Conditions attached",
         delivery_method_options: delivery_options)
524 525
  end
end
526
```
527

528 529
### Sending Emails without Template Rendering

530 531
There may be cases in which you want to skip the template rendering step and
supply the email body as a string. You can achieve this using the `:body`
532
option. In such cases don't forget to add the `:content_type` option. Rails
533
will default to `text/plain` otherwise.
534 535 536

```ruby
class UserMailer < ActionMailer::Base
V
Vijay Dev 已提交
537
  def welcome_email(user, email_body)
538 539 540 541
    mail(to: user.email,
         body: email_body,
         content_type: "text/html",
         subject: "Already rendered!")
542 543 544 545
  end
end
```

546 547
Receiving Emails
----------------
548

549 550 551 552
Receiving and parsing emails with Action Mailer can be a rather complex
endeavor. Before your email reaches your Rails app, you would have had to
configure your system to somehow forward emails to your app, which needs to be
listening for that. So, to receive emails in your Rails app you'll need to:
553

554
* Implement a `receive` method in your mailer.
555

556 557 558
* Configure your email server to forward emails from the address(es) you would
  like your app to receive to `/path/to/app/bin/rails runner
  'UserMailer.receive(STDIN.read)'`.
559

560 561 562 563
Once a method called `receive` is defined in any mailer, Action Mailer will
parse the raw incoming email into an email object, decode it, instantiate a new
mailer, and pass the email object to the mailer `receive` instance
method. Here's an example:
564

565
```ruby
566 567
class UserMailer < ActionMailer::Base
  def receive(email)
568
    page = Page.find_by(address: email.to.first)
569
    page.emails.create(
570 571
      subject: email.subject,
      body: email.body
572 573 574
    )

    if email.has_attachments?
575
      email.attachments.each do |attachment|
576
        page.attachments.create({
577 578
          file: attachment,
          description: email.subject
579 580 581 582 583
        })
      end
    end
  end
end
584
```
585

586 587 588
Action Mailer Callbacks
---------------------------

589 590
Action Mailer allows for you to specify a `before_action`, `after_action` and
`around_action`.
591

592 593
* Filters can be specified with a block or a symbol to a method in the mailer
  class similar to controllers.
594

595 596
* You could use a `before_action` to populate the mail object with defaults,
  delivery_method_options or insert default headers and attachments.
597

598 599
* You could use an `after_action` to do similar setup as a `before_action` but
  using instance variables set in your mailer action.
600 601 602

```ruby
class UserMailer < ActionMailer::Base
603 604 605
  after_action :set_delivery_options,
               :prevent_delivery_to_guests,
               :set_business_headers
606 607 608 609 610 611 612 613 614 615 616 617 618 619

  def feedback_message(business, user)
    @business = business
    @user = user
    mail
  end

  def campaign_message(business, user)
    @business = business
    @user = user
  end

  private

620 621 622 623 624 625
    def set_delivery_options
      # You have access to the mail instance,
      # @business and @user instance variables here
      if @business && @business.has_smtp_settings?
        mail.delivery_method.settings.merge!(@business.smtp_settings)
      end
626 627
    end

628 629 630 631
    def prevent_delivery_to_guests
      if @user && @user.guest?
        mail.perform_deliveries = false
      end
632 633
    end

634 635 636 637
    def set_business_headers
      if @business
        headers["X-SMTPAPI-CATEGORY"] = @business.code
      end
638 639 640 641 642 643
    end
end
```

* Mailer Filters abort further processing if body is set to a non-nil value.

644 645
Using Action Mailer Helpers
---------------------------
646

647 648
Action Mailer now just inherits from `AbstractController`, so you have access to
the same generic helpers as you do in Action Controller.
649

650 651
Action Mailer Configuration
---------------------------
652

653 654
The following configuration options are best made in one of the environment
files (environment.rb, production.rb, etc...)
655

656 657
| Configuration | Description |
|---------------|-------------|
658
|`logger`|Generates information on the mailing run if available. Can be set to `nil` for no logging. Compatible with both Ruby's own `Logger` and `Log4r` loggers.|
659
|`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default `"localhost"` setting.</li><li>`:port` - On the off chance that your mail server doesn't run on port 25, you can change it.</li><li>`:domain` - If you need to specify a HELO domain, you can do it here.</li><li>`:user_name` - If your mail server requires authentication, set the username in this setting.</li><li>`:password` - If your mail server requires authentication, set the password in this setting.</li><li>`:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain`, `:login`, `:cram_md5`.</li><li>`:enable_starttls_auto` - Set this to `false` if there is a problem with your server certificate that you cannot resolve.</li></ul>|
660
|`sendmail_settings`|Allows you to override options for the `:sendmail` delivery method.<ul><li>`:location` - The location of the sendmail executable. Defaults to `/usr/sbin/sendmail`.</li><li>`:arguments` - The command line arguments to be passed to sendmail. Defaults to `-i -t`.</li></ul>|
661
|`raise_delivery_errors`|Whether or not errors should be raised if the email fails to be delivered. This only works if the external email server is configured for immediate delivery.|
662
|`delivery_method`|Defines a delivery method. Possible values are:<ul><li>`:smtp` (default), can be configured by using `config.action_mailer.smtp_settings`.</li><li>`:sendmail`, can be configured by using `config.action_mailer.sendmail_settings`.</li><li>`:file`: save emails to files; can be configured by using `config.action_mailer.file_settings`.</li><li>`:test`: save emails to `ActionMailer::Base.deliveries` array.</li></ul>See [API docs](http://api.rubyonrails.org/classes/ActionMailer/Base.html) for more info.|
663 664 665
|`perform_deliveries`|Determines whether deliveries are actually carried out when the `deliver` method is invoked on the Mail message. By default they are, but this can be turned off to help functional testing.|
|`deliveries`|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.|
|`default_options`|Allows you to set default values for the `mail` method options (`:from`, `:reply_to`, etc.).|
666

667
For a complete writeup of possible configurations see the
668
[Configuring Action Mailer](configuring.html#configuring-action-mailer) in
669 670
our Configuring Rails Applications guide.

671
### Example Action Mailer Configuration
672

673 674
An example would be adding the following to your appropriate
`config/environments/$RAILS_ENV.rb` file:
675

676
```ruby
677 678 679
config.action_mailer.delivery_method = :sendmail
# Defaults to:
# config.action_mailer.sendmail_settings = {
680 681
#   location: '/usr/sbin/sendmail',
#   arguments: '-i -t'
682 683 684
# }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
685
config.action_mailer.default_options = {from: 'no-reply@example.com'}
686
```
687

688
### Action Mailer Configuration for Gmail
689

690 691
As Action Mailer now uses the [Mail gem](https://github.com/mikel/mail), this
becomes as simple as adding to your `config/environments/$RAILS_ENV.rb` file:
692

693
```ruby
694 695
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
696 697
  address:              'smtp.gmail.com',
  port:                 587,
698
  domain:               'example.com',
699 700 701 702
  user_name:            '<username>',
  password:             '<password>',
  authentication:       'plain',
  enable_starttls_auto: true  }
703
```
704

705 706
Mailer Testing
--------------
707

708
You can find detailed instructions on how to test your mailers in the
709
[testing guide](testing.html#testing-your-mailers).
710

711 712
Intercepting Emails
-------------------
713

714 715 716 717
There are situations where you need to edit an email before it's
delivered. Fortunately Action Mailer provides hooks to intercept every
email. You can register an interceptor to make modifications to mail messages
right before they are handed to the delivery agents.
718 719 720 721 722 723 724 725 726

```ruby
class SandboxEmailInterceptor
  def self.delivering_email(message)
    message.to = ['sandbox@example.com']
  end
end
```

727 728 729
Before the interceptor can do its job you need to register it with the Action
Mailer framework. You can do this in an initializer file
`config/initializers/sandbox_email_interceptor.rb`
730 731 732 733 734

```ruby
ActionMailer::Base.register_interceptor(SandboxEmailInterceptor) if Rails.env.staging?
```

735 736
NOTE: The example above uses a custom environment called "staging" for a
production like server but for testing purposes. You can read
737
[Creating Rails environments](configuring.html#creating-rails-environments)
738
for more information about custom Rails environments.