开发者

Rails3: rewrite url_for for subdomain support, how to extend action mailer to use such url_for

I take code from 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  

It is ok to use modified url_for in views of Controllers. But I have trouble with ActionMailer.

I tried to use following:

class Notifier < ActionMailer::Base
  include UrlHelper
end

But ActionMailer views still use old unmodified url_for from ActionDispatch::Routing::RouteSet.

What is the best practice to add new url_for


Add the following code to the file app/helpers/url_helper.rb:

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

and modify the file app/controllers/application_controller.rb to add:

before_filter :set_mailer_url_options

Source


I have a solution for this issue but I don't think it is still the best way to do it. I have tried and will still try to come up with a better solution but here is what I have done in my email template. The reason I put this in the email template is because I'm using Devise, but I'm hoping to come up with something better.

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

You can pass the host to the url_for now like this

user_confirmation_url(:host => host)


I found the simplest solution on Rails 3.0.x was to construct the host-with-subdomain manually in every URL in my mailer views. For example:

Your account is here:

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

-- where your @account model knows its subdomain.

This in nice and simple, threadsafe, and isolated. You don't need to pollute other parts of your codebase. And it's easy to back out once you move to Rails 3.1.x, which should handle all this automatically I believe.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜