Rails3:重写url_for以获得子域支持,如何扩展动作邮件程序以使用这样的url_for

时间:2010-11-15 20:17:11

标签: ruby-on-rails actionmailer subdomain url-for

我从Subdomain RailsCast

获取代码
module UrlHelper
  def with_subdomain(subdomain)
    subdomain = (subdomain || "")
    subdomain += "." unless subdomain.empty?
    [subdomain, request.domain, request.port_string].join
  end

  def url_for(options = nil)
    if options.kind_of?(Hash) && options.has_key?(:subdomain)
      options[:host] = with_subdomain(options.delete(:subdomain))
    end
    super
  end
end

class ApplicationController < ActionController::Base
  include UrlHelper
end  

可以在控制器的视图中使用修改后的url_for。但我在使用ActionMailer时遇到了麻烦。

我尝试使用以下内容:

class Notifier < ActionMailer::Base
  include UrlHelper
end

但是ActionMailer视图仍然使用来自ActionDispatch :: Routing :: RouteSet的旧的未修改的url_for。

添加新url_for

的最佳做法是什么

3 个答案:

答案 0 :(得分:5)

将以下代码添加到文件app / helpers / url_helper.rb:

def set_mailer_url_options
    ActionMailer::Base.default_url_options[:host] = with_subdomain(request.subdomain)
end

并修改文件app / controllers / application_controller.rb以添加:

before_filter :set_mailer_url_options

Source

答案 1 :(得分:1)

我有一个解决这个问题的方法,但我认为它仍然是最好的方法。我已经尝试过并且仍然会尝试提出更好的解决方案,但这是我在电子邮件模板中所做的。我把它放在电子邮件模板中的原因是因为我正在使用Devise,但我希望能找到更好的东西。

subdomain = @resource.account.subdomain
subdomain = (subdomain || "")
subdomain += "." unless subdomain.empty?
host = [subdomain, ActionMailer::Base::default_url_options[:host]].join

您可以像现在这样将主机传递给url_for

user_confirmation_url(:host => host)

答案 2 :(得分:0)

我发现Rails 3.0.x上最简单的解决方案是在我的邮件程序视图中的每个URL中手动构建host-with-subdomain。例如:

Your account is here:

<%= account_url(:host => "#{@account.subdomain}.#{ActionMailer::Base.default_url_options[:host]}" %>

- 您的@account模型知道其子域名。

这很简单,线程安全,孤立。您不需要污染代码库的其他部分。一旦你转移到Rails 3.1.x就很容易退出,它应该自动处理所有这些我认为。