如何将ActionMailer的default_url_options的:host动态设置为请求的主机名?

45

我正在尝试设置Action Mailer默认URL选项的:host。

在所有环境文件中,我都有以下设置:

config.action_mailer.default_url_options = {
  :host => "localhost"
}

我希望通过提供请求主机使其更加动态。

当我尝试通过以下方式进行设置时:

config.action_mailer.default_url_options = {
  :host => request.domain
}
或者
config.action_mailer.default_url_options = {
  :host => request.env["SERVER_NAME"]
}

出现错误...无法识别“request”对象。

是否有任何方法可以将其设置为请求主机,而不是硬编码...?

3个回答

51

通过在default_url_options哈希中设置:host选项,还可以设置一个默认主机,该主机将由所有邮件发送程序使用。

application_controller.rb中添加:

class ApplicationController < ActionController::Base
  def default_url_options
    { host: request.host_with_port }
  end
end

来源:https://edgeguides.rubyonrails.org/action_controller_overview.html#default-url-options

或者,当从控制器调用邮件函数时,您可以传递request参数。

class UserMailer < ActionMailer::Base

  def welcome_email(user, request)
    @user = user
    @url  = user_url(@user, host: request.host_with_port ) # do this for each link
    mail(:to => user.email, :subject => "Welcome to My Awesome Site")
  end
end

来源: https://guides.rubyonrails.org/action_mailer_basics.html#generating-urls-with-named-routes


16
ActionMailer::Base无法访问请求对象。 - Brad Werth
3
before filter方法能够正常运作,但不具备线程安全性,因此仅适用于单一域的情况。 - Brad Werth
1
在使用filter方法之前,根据每个环境删掉'config.action_mailer.default_url_options'! :) - Szymon Przybył
@BradWerth,您能否再解释一下为什么这只适用于使用单个域的应用程序? - pixelearth
@pixelearth 类似于 https://dev59.com/_Jnga4cB1Zd3GeqPWEM-,但是针对主机。 - Brad Werth
@BradWerth是正确的,我已经更新了这个答案以确保线程安全。 - montrealmike

11

显然(令人恼火的是),这种做法不再被允许。我收到了以下错误信息:RuntimeError(您不能再直接调用ActionMailer :: Base.default_url_options。您需要设置config.action_mailer.default_url_options。如果您正在使用独立的ActionMailer,则需要直接包含路由url_helpers。) - ndbroadbent
不确定 @nathan.f77。我可以这样设置它:ActionMailer::Base.default_url_options = {:host => request.host_with_port} - SooDesuNe
@SooDesuNe,那个现在已经被弃用了。你不能再直接设置它了。 - iwasrobbed
那么解决方案是什么呢?在我的看法中,虽然通过配置对象在初始化器中设置事物很有用,但在ActionMailer初始化后始终应该有一种修改配置的方法... 但这在Rails 3.0.9中似乎仍然可以正常工作,所以我想现在还可以这样做... - Tyler Rick
只是想插一句话并说,即使是最新发布的 Rails 3.2,这种方法对我来说仍然完美运作。使用子域名,这真是救命稻草。谢谢! - Eric
1
请使用这个线程安全的解决方案:https://dev59.com/VHE85IYBdhLWcg3wr1ke - Doug

6
问题在于这些是初始化程序,它们在 Rails 栈加载时运行,而不是在调用 active mailer 时运行。
但是您不必使用 default_url,您可以在每个邮件视图中将主机名传递到 url_for/named routes 中。默认值只是避免了这样做的需要。
请参见生成 URL 的 http://api.rubyonrails.org/classes/ActionMailer/Base.html 部分。

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