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: "firstname.lastname@example.org") UserMailer.with(user: user).confirmation end end
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
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
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
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