---
title: You've Got Mail
teaser:
tags: web,rails
author: Josh Clayton
published_on: 2009-09-09
---

There are just some days when you want to interact with *real* data from a Rails
application that you wrote.  Doing a database dump, saving the output locally,
and loading that data in is the ideal method, but once you do that, _you've got
live data locally_.  This can be a Bad Thing&trade; if you're sending email.

Why?

Mailers can be triggered in any number of places.  A callback, a controller, or
an observer could be sitting there, waiting to send off an email to an
unsuspecting victim without you being aware.  This is one reason why playing
with live data is a bit dangerous.  There's luckily an easy workaround.

![You've Got Mail](http://thoughtbot.widgetfinger.com/assets/48/original/you_ve_got_mail.jpg)

`ActionMailer::Base` has an instance method, `recipients`, that accepts a string
of email addresses to whom you'll be sending your message.  If we override that
method in the mailer classes we don't want sending email, we can intercept any
calls and replace recipients if we want.

```ruby
class ProductMailer < ActionMailer::Base
  # mailer methods

  def recipients(*emails)
    if emails.size == 1
      super(MAILER_RECIPIENT_OVERRIDE || emails.first)
    else
      super(*emails)
    end
  end
end
```

Using Ruby, we overload the recipients method and call `super`, passing our
`MAILER_RECIPIENT_OVERRIDE` constant *or* the email addresses that were passed.
Because our mailer inherits from `ActionMailer::Base`, `super` will relay the
constant or whatever was passed; if the constant is `nil`, the recipients will
work normally.  However, in our development environment (for example), if that
constant is assigned a string, the email will be delivered to the email instead.

Where does this leave us?

We're going to want to assign values to this constant for each of our
environments.  In `config/environments/development.rb` (or whichever environment
you dumped the live data into), we'll want to assign this to a string.  I like
sending everything to "test@example.com".  Within our other environments, we'll
want this set to `nil` so it doesn't affect our tests or production site emails.

```ruby
# config/environments/development.rb
MAILER_RECIPIENT_OVERRIDE = "test@example.com"

# config/environments/staging.rb
MAILER_RECIPIENT_OVERRIDE = "test@example.com"

# config/environments/test.rb
MAILER_RECIPIENT_OVERRIDE = nil

# config/environments/production.rb
MAILER_RECIPIENT_OVERRIDE = nil
```

This solution provides a quick, simple way to override recipients without
cluttering up the code and allows a flexible solution when dealing with live
data.

There is a caveat, however.  You have to do this for every mailer.  There are
ways around this (like creating an `ApplicationMailer` base class that your
mailers inherit from), but unless you're dealing with a bunch of mailers,
defining recipients in each is a perfectly acceptable solution.
