Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I preview emails in Rails?

This might be a dumb question but when I'm putting together an HTML email in Rails, is there a particularly easy built-in way to preview the template it in the browser or do I need to write some sort of custom controller that pulls it in as its view?

like image 861
Peter Nixey Avatar asked Aug 23 '11 17:08

Peter Nixey


People also ask

What are Mailers in Rails?

Mailers are really just another way to render a view. Instead of rendering a view and sending it over the HTTP protocol, they are sending it out through the email protocols instead. Due to this, it makes sense to have your controller tell the Mailer to send an email when a user is successfully created.

What is Default_url_options?

The default_url_options setting is useful for constructing link URLs in email templates. Usually, the :host , i.e. the fully qualified name of the web server, is needed to be set up with this config option. It has nothing to do with sending emails, it only configures displaying links in the emails.


13 Answers

Action Mailer now has a built in way of previewing emails in Rails 4.1. For example, check this out:

# located in test/mailers/previews/notifier_mailer_preview.rb

class NotifierPreview < ActionMailer::Preview
  # Accessible from http://localhost:3000/rails/mailers/notifier/welcome
  def welcome
    Notifier.welcome(User.first)
  end
end
like image 156
benjaminjosephw Avatar answered Oct 14 '22 13:10

benjaminjosephw


Daniel's answer is a good start, but if your email templates contain any dynamic data, it won't work. E.g. suppose your email is an order receipt and within it you print out @order.total_price - using the previous method the @order variable will be nil.

Here's a little recipe I use:

First, since this email preview functionality is definitely for internal use only, I set up some generic routes in the admin namespace:

#routes.rb

MySite::Application.routes.draw do
  namespace :admin do
    match 'mailer(/:action(/:id(.:format)))' => 'mailer#:action'
  end
end

Next, I create the controller. In this controller, I create one method per email template. Since most emails contain dynamic data, we need to populate whatever member variables the template expects.

This could be done with fixtures, but I typically prefer to just grab some pseudo-random real data. Remember - this is NOT a unit test - this is purely a development aid. It doesn't need to produce the same result every single time - in fact - it's probably better if it doesn't!

#app/controllers/admin/mailer_controller.rb
class Admin::MailerController < Admin::ApplicationController

  def preview_welcome()
    @user = User.last
    render :file => 'mailer/welcome.html.erb', :layout => 'mailer'
  end

end

Note that when we render the template, we use layout=>:mailer. This embeds the body of your email inside the HTML email layout that you've created instead of inside your typical web application layout (e.g. application.html.erb).

And that's pretty much it. Now I can visit http://example.com/admin/mailer/preview_welcome to preview change to my welcome email template.

like image 30
cailinanne Avatar answered Oct 14 '22 13:10

cailinanne


37Signals also has their own mail testing gem called mail_view. It's pretty fantastic.

like image 25
Marc Avatar answered Oct 14 '22 15:10

Marc


The easiest setup I've seen is MailCatcher. Setup took 2 minutes, and it works for new mailers out of the box.

like image 42
Galen Avatar answered Oct 14 '22 15:10

Galen


I use email_preview. Give it a try.

like image 38
Pikachu Avatar answered Oct 14 '22 15:10

Pikachu


Easiest solution in rails 6: just remember one url:

http://localhost:3000/rails/mailers

like image 42
stevec Avatar answered Oct 14 '22 14:10

stevec


I'm surprised no one's mentioned letter_opener. It's a gem that will render and open emails as a browser page whenever an email is delivered in dev.

like image 29
KurtPreston Avatar answered Oct 14 '22 14:10

KurtPreston


I recently wrote a gem named Maily to preview, edit (template file) and deliver the application emails via a browser. It also provides a friendly way to hook data, a flexible authorization system and a minimalist UI.

I have planned to add new features in the near future, like:

  • Multiple hooks per email
  • Parametrize emails via UI (arguments of mailer method)
  • Play with translations keys (list, highlight, ...)

I hope it can help you.

like image 28
markets Avatar answered Oct 14 '22 13:10

markets


rails generates a mail preview if you use rails g mailer CustomMailer. You will get a file CustomMailerPreview inside spec/mailers/previews folder.

Here you can write your method that will call the mailer and it'll generate a preview.

For ex -

class CustomMailerPreview < ActionMailer::Preview
  def contact_us_mail_preview
    CustomMailer.my_mail(user: User.first)
  end
end

Preview all emails at http://localhost:3000/rails/mailers/custom_mailer

like image 43
Swaps Avatar answered Oct 14 '22 14:10

Swaps


You can use Rails Email Preview

rails-email-preview screenshot

REP is a rails engine to preview and test send emails, with I18n support, easy premailer integration, and optional CMS editing with comfortable_mexican_sofa.

like image 34
glebm Avatar answered Oct 14 '22 14:10

glebm


There is no way to preview it directly out of the Mailer. But as you wrote, you can write a controller, which looks something like this.

class EmailPreviewsControllers < ActionController::Base
  def show
    render "#{params[:mailer]}_mailer/#{params[:method]}"
  end
end

But I think, that's not the best way to test emails, if they look correctly.

like image 42
Daniel Spangenberg Avatar answered Oct 14 '22 14:10

Daniel Spangenberg


Rails Email Preview helps us to quickly view the email in web browser in development mode.

1) Add “gem ‘rails_email_preview’, ‘~> 0.2.29’ “ to gem file and bundle install.

2) Run “rails g rails_email_preview:install” this creates initializer in config folder and add routes.

3) Run “rails g rails_email_preview:update_previews” this crates mailer_previews folder in app directory.

Generator will add a stub to each of your emails, then u populate the stub with mock data.

Ex:

class UserMailerPreview
def invitation
UserMailer.invitation mock_user(‘Alice’), mock_user(‘Bob’)
end
def welcome
UserMailer.welcome mock_user
end
private
def mock_user(name = Bill Gates’)
fake_id User.new(name: name, email: user#{rand 100}@test.com”)
end
def fake_id(obj)
obj.define_singleton_method(:id) { 123 + rand(100) }
obj
end
end

4) Parameters in search query will be available as an instance variable to preview class. Ex: if we have a URL like “/emails/user_mailer_preview-welcome?user_id=1” @user_id is defined in welcome method of UserMailerPreview it helps us to send mail to specific user.

class UserMailerPreview
def welcome
user = @user_id ? User.find(@user_id) : mock_user
UserMailer.welcome(user)
end
end

5) To access REP url’s like this

rails_email_preview.rep_root_url
rails_email_preview.rep_emails_url
rails_email_preview.rep_email_url(‘user_mailer-welcome’)

6) We can send emails via REP, this will use environment mailer settings. Uncomment this line in the initializer to disable sending mail in test environment.

config.enable_send_email = false

Source : RailsCarma Blog : Previewing Emails in Rails Applications With the Mail_View Gem

like image 42
Carma Tec Avatar answered Oct 14 '22 15:10

Carma Tec


I prefer mails_viewer gem. This gem is quite useful as it save the HTML template into tmp folder.

like image 44
Trung Lê Avatar answered Oct 14 '22 15:10

Trung Lê