13

I am using rails 4.1.1 and ActionMailer::Preview for previewing emails. In development environment everything is working excellent.

But in production environment the preview routes are not accessible. I store the previews in test/mailers/previews/

Is is possible to enable them for production?

Todd
  • 3,438
  • 1
  • 27
  • 36
hpeev
  • 185
  • 3
  • 11

5 Answers5

16

In addition to this:

config.action_mailer.show_previews = true

you will also need to set

config.consider_all_requests_local = true

in your environment for the preview routes to be accessible. This has other implications as well (see https://stackoverflow.com/a/373135/1599045) so you likely don't want to enable this in production. However, if you have a custom environment that's not development, the combination of those two should get things working.

EDITED TO ADD:

The original question was for rails 4.1.1, which doesn't have config.action_mailer.show_previews available. To get ActionMailer previews working in non-development environments in rails 4.1.1, you need to first add some routes to config/routes.rb (in this case, my environment is named custom):

if Rails.env.custom?
  get '/rails/mailers'         => "rails/mailers#index"
  get '/rails/mailers/*path'   => "rails/mailers#preview"
end

Then you need to autoload the libraries needed in your environment's config file (in my case, config/environments/custom.rb):

config.action_mailer.preview_path ||= defined?(Rails.root) ? "#{Rails.root}/test/mailers/previews" : nil
config.autoload_paths += [config.action_mailer.preview_path]

This seems to perform the same task as config.action_mailer.show_previews does.

As with 4.2, you will still need to adjust the local request configuration as above depending on whether your custom environment is being used locally or on a server.

Community
  • 1
  • 1
joel boonstra
  • 425
  • 3
  • 12
  • I've had to switch `config.cache_classes = false` in order to get it working in 4.2.2, untested in any other release. – iNulty Nov 29 '15 at 16:45
  • 2
    A word of warning that you should absolutely NOT set `config.consider_all_requests_local` as this will dump error messages to the browser, the same as you see while in development mode. You definitely don't want to do this in a production environment that has regular users out in the world. See the "To do it without open a big security hole" answer in this thread! – Rob Cameron Oct 31 '16 at 23:52
15

To do it without opening a big security hole:

production.rb

MyApp::Application.configure do
  config.action_mailer.preview_path ||= defined?(Rails.root) ? "#{Rails.root}/spec/mailer_previews" : nil
  config.autoload_paths += [config.action_mailer.preview_path]

  routes.append do
    get '/rails/mailers'         => "rails/mailers#index"
    get '/rails/mailers/*path'   => "rails/mailers#preview"
  end
end

class ::Rails::MailersController
  before_filter :authenticate_admin!
  def local_request?
    true
  end
  private
  def authenticate_admin!
    ...
  end
end
Community
  • 1
  • 1
Michael Johnston
  • 5,298
  • 1
  • 29
  • 37
  • 3
    I get adding the `before_filter` and overriding the `local_request?` method for the `::Rails::MailersController` class. But the changes for the `MyApp::Application.configure` section seem unnecessary. Seems like the secure way would be to set `config.action_mailer.show_previews = true` and then use the bottom part of what you suggested. Can you help me understand about the paths and routes? – cwd May 31 '18 at 17:13
3

It's possible to enable previews in production by config.action_mailer.show_previews = true as the best answer says.

I just want to add how you can render previews in iframe within your own admin area, eg. in active admin (Rails 5.1)

And also I found out that it is not so hard to write your own email previews administration, and don't use rails standard previews at all. You can then add your own features such as changing preview parameters or Send button to see this email in your phone.

Lev Lukomsky
  • 6,346
  • 4
  • 34
  • 24
2

From Rails 4.2 you can use the flag in production.rb (or other custom enviroment):

config.action_mailer.show_previews = true

I haven't found anything similar in Rails 4.1.

Update:
If Rspec used, for example, there will be need to add the path:

config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews"

Default path is "#{Rails.root}/test/mailers/previews".

And no need to touch config.consider_all_requests_local

Alexandr
  • 1,704
  • 1
  • 14
  • 20
Nik
  • 29
  • 2
  • 3
    The application responds with "For security purposes, this information is only available to local requests." if we try to execute it in the server – Tania R Jun 30 '15 at 08:30
  • you should also add `config.consider_all_requests_local = true` – Ich Jan 26 '16 at 09:03
  • 2
    I'm on Rails 5 and this one setting worked for me. The mail previews are available to the entire world, however. We'll have to come up with something to block non-admin users. Note that it is a very bad idea to set `config.consider_all_requests_local = true` in a production environment—users will see the internal stack trace and error messages rather than your 404 or 500 page. – Rob Cameron Nov 02 '16 at 16:55
2

Here's what I did for Rails 5.2:

production.rb

  config.action_mailer.show_previews = true
  config.action_mailer.preview_path ||= defined?(Rails.root) ? "#{Rails.root}/spec/mailers/previews" : nil

  class ::Rails::MailersController
    include ::ApplicationController::Authorization
    before_action :require_admin
  end

Assuming your ApplicationController::Authorization module has the code for require_admin. I preferred this approach rather than rewriting my authorization code. Remembering to include the :: in front was tricky, because saying include ApplicationController::... will look within the Rails::MailersController namespace.

Andrew Smith
  • 1,434
  • 13
  • 29