How to avoid ActionMailer::Preview committing data to development database?
actionmailer, ruby-on-rails
Solution
Cleaner/Easier (based on other answers) and tested with Rails 7: Do not change Rails' classes but create your own. Id addition to not change the controller but the `call` method of `ActionMailer::Preview`.
# app/mailers/preview_mailer.rb
class PreviewMailer < ActionMailer::Preview
def self.call(...)
message = nil
ActiveRecord::Base.transaction do
message = super(...)
raise ActiveRecord::Rollback
end
message
end
end
# inherit from `PreviewController` for your previews
class EventInvitationPreview < PreviewController
def invitation_email
...
end
end
OLD:
You can simply use a transaction around email previews, just put this inside your `lib/monkey_mailers_controller.rb` (and require it):
# lib/monkey_mailers_controller.rb
class Rails::MailersController
alias_method :preview_orig, :preview
def preview
ActiveRecord::Base.transaction do
preview_orig
raise ActiveRecord::Rollback
end
end
end
Then you can call `.create` etc. in your mailer previews but nothing will be saved to database. Works in `Rails 4.2.3`.
Problem
I'm using `Rails 4.1.0.beta1`'s new Action Mailer previews and have the following code: ``` class EventInvitationPreview < ActionMailer::Preview def invitation_email invite = FactoryGirl.create :event_invitation, :for_match, :from_user, :to_user EventInvitationMailer.invitation_email(invite) end end ``` This is all good until I actually try to preview my email and get an error saying that validation on a User object failed due to duplicate email addresses. Turns out that ActionMailer::Preview is writing to my development database. While I could work around the validation failure or use fixtures instead of factories, is there any way to avoid ActionMailer::Preview writing to the development database, e.g. use the test database instead? Or am I just doing it wrong?