Accessing request.host in UserMailer

I am using subdomains in my application to control context. Therefor, during user registration, password reset, and other actions that require an email to be sent with a link to be clicked, I need to ensure that the subdomain appropriate for the user is used.

It seems I need to be able to access request.host from within an ActionMailer model. But I am not clear how to do this.

Any help would be greatly appreciated.

best, Tom

Tom Hoen wrote:

I am using subdomains in my application to control context. Therefor, during user registration, password reset, and other actions that require an email to be sent with a link to be clicked, I need to ensure that the subdomain appropriate for the user is used.

It seems I need to be able to access request.host from within an ActionMailer model. But I am not clear how to do this.

You'll have to supply the request object as a parameter to mailer calls made in your controllers.

Here's an outline of one way to do this:

class MyMailer < ActionMailer::Base    def initialize(method_name, request, *params)      @host = request.host_with_port      super(method_name, *params)    end

   def url_for(params)      url_for_without_host(params.update(:host => @host))    end    alias_method_chain :url_for, :host

   def doit(param1, param2)      body :link => url_for(:controller => :user, :action => :rego)    end end

MyMailer.deliver_doit(request, param1, param2)

If you're not running multi-threaded you can instead set the mailer default_url_options host in a before_filter, allowing everything to work automatically.

Tom Hoen wrote:

Mark Reginald James wrote:

You'll have to supply the request object as a parameter to mailer calls made in your controllers.

Mark, I appreciate the quick response.

Unfortunately, I am using an Observer to initiate the emails. So I don't think I have access to the request object when the deliver call is made.

Is there any other way to access it?

Tom, perhaps you can use the second method I described, but make it thread-safe:

before_filter 'Thread.current[:host] = request.host_with_port'

def url_for(params)    url_for_without_host(params.update(:host => Thread.current[:host])) end alias_method_chain :url_for, :host

Mark Reginald James wrote:

Tom, perhaps you can use the second method I described, but make it thread-safe:

before_filter 'Thread.current[:host] = request.host_with_port'

Does this describe what your are suggesting:

It looks like there is some concern about Thread.current and the webserver being used. Do you know if it works with Passenger?

Thanks Tom

Interesting question -- I just did a quick test by adding this line     Thread.current[:wtf] = request.user_agent to a controller in an app, and fetching a page displaying that variable with three different browsers using Apache 2.2.9 + Passenger 2.0.3 (on OS X).

In each case I got the expected (different) user agent string.

Probably not definitive, but FWIW!