Having production data in a staging environment makes it easier to catch bugs.
But when testing a feature, there's always that tiny moment of hesitation when you hit the "Send Email" button.
Will this actually go out to a real user?
I'm sure most of you have been there.
For local development, we usually install the excellent letter_opener gem. But what about staging?
Safely sending emails in staging
Rails 7.1+ introduced a new before_deliver callback for Action Mailers, which
is perfect for overriding recipients before emails are actually sent.
Here's how to use it:
class ApplicationMailer < ActionMailer::Base
before_deliver :override_recipients
private
def override_recipients
return unless Rails.env.staging?
sandbox_emails = ENV.fetch("SANDBOX_EMAILS")
message.to = sandbox_emails
message.cc = sandbox_emails
message.bcc = sandbox_emails
end
end
Just make sure you have the SANDBOX_EMAILS environment variable set. Or pull
it from Rails credentials if you prefer.
If you're on an older version of Rails (< 7.1), you can use interceptor to
accomplish the same thing:
# app/mailers/sandbox_email_interceptor.rb
class SandboxEmailInterceptor
def self.delivering_email(message)
sandbox_emails = ENV.fetch("SANDBOX_EMAILS")
message.to = sandbox_emails
message.cc = sandbox_emails
message.bcc = sandbox_emails
end
end
The interceptor needs to be registered using the interceptors option of
action_mailer.
# config/initializers/mail_interceptors.rb
Rails.application.configure do
if Rails.env.staging?
config.action_mailer.interceptors = %w[SandboxEmailInterceptor]
end
end
That is it. You can now click "Send Email" without the panic.
Want help setting up safer Rails environments? Our Ruby on Rails development services help teams avoid costly mistakes.