什么是 ActionMailer default_url_options?

What is ActionMailer default_url_options?

我一定不明白关于电子邮件的一些琐碎的事情,但是 defaul_url_options 中的主机是做什么的? smtp 设置的需要对我来说很有意义,可以配置电子邮件的发送方式,但 default_url_options 与此有什么关系?

  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  host = '<your heroku app>.herokuapp.com'
  config.action_mailer.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    :address        => 'smtp.sendgrid.net',
    :port           => '587',
    :authentication => :plain,
    :user_name      => ENV['SENDGRID_USERNAME'],
    :password       => ENV['SENDGRID_PASSWORD'],
    :domain         => 'heroku.com',
    :enable_starttls_auto => true
  }

default_url_options 设置对于在电子邮件模板 中构建 link URL 很有用。通常,需要使用此配置选项设置 :host,即 Web 服务器的完全限定名称。与发送邮件无关,只是配置在邮件中显示links

Rails Guides as well ActionMailer::Base sources:

中详细记录了设​​置此项的必要性

URLs can be generated in mailer views using url_for or named routes. Unlike controllers from Action Pack, the mailer instance doesn't have any context about the incoming request, so you'll need to provide all of the details needed to generate a URL.

When using url_for you'll need to provide the :host, :controller, and :action:

<%= url_for(host: "example.com", controller: "welcome", action: "greeting") %>

When using named routes you only need to supply the :host

<%= users_url(host: "example.com") %>

因此,为了改写文档,在网页中,当前 Web 服务器的名称(将在绝对 links 中使用)取自传入的请求信息。但是在呈现电子邮件时您没有此信息可用(没有请求),这就是为什么您必须手动提供它,以便电子邮件中的 links 正常工作。

您是否尝试过在 ActionMailer 模板中生成 URLs?如果您至少做过一次,那么您可能熟悉以下错误:

ActionView::TemplateError (Missing host to link to! Please provide :host parameter or set default_url_options[:host])

发生这种情况是因为 ActionMailer 实例没有任何关于传入请求的上下文,因此您需要提供 :host、:controller 和 :action:。如果您使用命名路由,ActionPack 会为您提供控制器和操作名称。否则,使用 url_for 帮助程序,您需要传递所有参数。

<%= message_url %>
<%= url_for :controller => "messages", :action => "index" %>

无论您的选择如何,您始终需要提供主机选项​​以在 ActionMailer 中生成 URL。如 ActionMailer 指南所示,您基本上有两种方法将主机值传递给 ActionMailer:

1. set a global value
2. pass the option each time you generate an URL

定义 default_url_options 比每次传递 URL 更好 。 这就是我们这样做的原因。