Using Callbacks in Rails 3 ActionMailer


When working with ActionMailer (Rails 3) it feels so similar to how controllers work that I thought it was odd that I couldn’t use callbacks such as before_filter or after_filter. While there are drop in gems or examples showing how to use interceptors I figured there had to be a way to reuse callbacks.

Luckily, I came across an accepted pull request that includes callbacks in ActionMailer but only for Rails 4. After reviewing the commit its very easy to add support for Rails 3 since all we need to do is include the AbstractController::Callbacks module in our mailer class and from there we can define our callbacks.

The example below shows how I resolved an issue where I needed to change the recipient address for any outgoing emails when in the staging environment.

class Mailer < ActionMailer::Base
  include AbstractController::Callbacks
  
  after_filter :send_to_admin_if_staging
  
  def send_to_admin_if_staging
    if Rails.env.staging?
      message.to = 'admin@my-app.com'
    end
  end
end

Besides access to message we also have access to mail in callbacks. This is useful if you prefer to stop email delivery or perhaps change other mail settings.

after_filter :stop_delivery_if_staging

def stop_delivery_if_staging
  if Rails.env.staging?
    mail.perform_deliveries = false
  end
end

Enjoyed the read? Follow me on Twitter or subscribe to my feed.