在生产环境中预览Rails ActionMailer

13
我正在使用Rails 4.1.1和ActionMailer::Preview来预览电子邮件。在开发环境中一切都运行得很好。
但是在生产环境中,预览路由无法访问。我将预览存储在test/mailers/previews/目录下。
有没有可能在生产环境中启用它们?
5个回答

16
此外:
config.action_mailer.show_previews = true

你还需要设置。
config.consider_all_requests_local = true

在您的环境中,预览路由才能访问。这也有其他影响(参见https://dev59.com/43RC5IYBdhLWcg3wOOP1#373135),所以您可能不想在生产环境中启用此功能。然而,如果您有一个自定义环境不是development,这两者的组合应该能够使事情正常工作。 编辑以添加: 原始问题是针对rails 4.1.1的,该版本没有config.action_mailer.show_previews可用。要在rails 4.1.1中使ActionMailer预览在非开发环境中工作,您需要首先在config/routes.rb中添加一些路由(在这种情况下,我的环境名为custom)。
if Rails.env.custom?
  get '/rails/mailers'               => "rails/mailers#index"
  get 'rails/mailers/download/*path' => "rails/mailers#download"
  get '/rails/mailers/*path'         => "rails/mailers#preview"
end

然后,您需要在环境配置文件中自动加载所需的库(在我的情况下,是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]

这似乎执行与 config.action_mailer.show_previews 相同的任务。
与4.2版本一样,您仍然需要根据您的自定义环境是在本地还是在服务器上使用来调整本地请求配置。

我不得不切换 config.cache_classes = false 才能在4.2.2中使其正常工作,在其他版本中未经测试。 - iNulty
2
警告一句,绝对不要设置config.consider_all_requests_local,因为这会将错误消息转储到浏览器中,就像在开发模式下看到的那样。您绝对不想在拥有常规用户的生产环境中这样做。请参见此线程中“如何在不打开大安全漏洞的情况下完成”答案! - Rob Cameron

15

要做到这一点而不打开一个大的安全漏洞:

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

3
我理解了在::Rails::MailersController类中添加before_filter和覆盖local_request?方法的操作。但是对于MyApp::Application.configure部分的更改似乎是不必要的。看起来更安全的方式是设置config.action_mailer.show_previews = true,然后使用您建议的底部部分。您能帮我理解路径和路由方面的内容吗? - cwd

3

如最佳答案所说,可以通过config.action_mailer.show_previews = true在生产环境中启用预览。

我想补充一下,您如何在自己的管理区域内使用iframe呈现预览,例如在active admin(Rails 5.1)中。

而且我发现编写自己的电子邮件预览管理并不难,并且完全不使用rails标准预览。然后,您可以添加自己的功能,例如更改预览参数或发送按钮以在手机上查看此电子邮件。


2

从Rails 4.2开始,您可以在production.rb(或其他自定义环境)中使用该标志:

config.action_mailer.show_previews = true

在Rails 4.1中,我没有找到类似的东西。

更新:
如果使用Rspec,例如,需要添加路径:

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

默认路径为"#{Rails.root}/test/mailers/previews"。

无需更改config.consider_all_requests_local。


3
如果我们尝试在服务器上执行该应用程序,它会响应“出于安全考虑,此信息仅对本地请求可用。” - Tania R
你还应该添加 config.consider_all_requests_local = true - Ich
2
我正在使用 Rails 5,这个设置适用于我。邮件预览对整个世界可见,因此我们需要想出一些方法来阻止非管理员用户。请注意,在生产环境中设置 config.consider_all_requests_local = true 是一个非常糟糕的想法——用户将看到内部堆栈跟踪和错误消息,而不是您的 404 或 500 页面。 - Rob Cameron

2
这是我为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

假设你的ApplicationController::Authorization模块中含有require_admin代码。我更喜欢这种方法,而不是重写我的授权代码。记得在前面加上::有点棘手,因为说include ApplicationController::...会在Rails::MailersController命名空间内查找。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接