DEV Community

Juraj Kostolanský
Juraj Kostolanský

Posted on • Originally published at kostolansky.sk

1

How to wrap Rails mailer previews in a database transaction

Most of the web applications today need to send some kind of email. In Ruby on Rails, this is an easy task. Just use the Action Mailer, create the email content, set up the SMTP configuration and you are ready to go.

The hardest part of this process is the content creation. Especially if you are building a multi-language application, seeing the big picture just from the source code can be quite hard. Fortunately, Rails provides a way to see how these emails look right in a web browser, using the Action Mailer Previews. Just create a class that inherits from the ActionMailer::Preview and call the required mailer action.

# test/mailers/previews/user_mailer_preview.rb

class UserMailerPreview < ActionMailer::Preview
  def confirmation
    user = User.new(email: "tester@example.com")
    UserMailer.with(user: user).confirmation
  end
end
Enter fullscreen mode Exit fullscreen mode

However, sometimes your mailer expects the ID of a record in the database, not the object itself. And sometimes you need to prepare this record, for example to create a new email confirmation token.

# test/mailers/previews/user_mailer_preview.rb

class UserMailerPreview < ActionMailer::Preview
  def confirmation
    user = User.first
    user.prepare_token!(:confirmation)
    UserMailer.with(user_id: user.id).confirmation
  end
end
Enter fullscreen mode Exit fullscreen mode

But this should be just a temporary change. Sure, you can wrap the whole method in a database transaction and use the database rollback command. But… How exactly?

Fortunately, there is an easy way to accomplish this using some Rails monkey patching. Just create the following module:

# lib/core_extensions/mailer_preview_rollback

module CoreExtensions
  module MailerPreviewRollback
    def preview
      ActiveRecord::Base.transaction do
        super
        raise ActiveRecord::Rollback
      end
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Create an initializer in your Ruby on Rails application and prepend this module:

# config/initializers/mailer_preview_rollback.rb

Rails.configuration.after_initialize do
  require "core_extensions/mailer_preview_rollback"
  Rails::MailersController.prepend CoreExtensions::MailerPreviewRollback
end
Enter fullscreen mode Exit fullscreen mode

And voila! All of your mailer previews are now safely wrapped in a database transaction.


Original article: How to wrap Rails mailer previews in a database transaction

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay