45

I am trying to set the :host for action mailer default url options.

I have the below set in all the environment files

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

I want to make it more dynamic by providing the request host.

when I try to set it by

config.action_mailer.default_url_options = {
  :host => request.domain
}

OR

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

It throws error... doesn't recognize "request" object

is there any way I can set this to the request host, not by hardcoding...?

mwallace
  • 137
  • 9
Madhusudhan
  • 8,374
  • 12
  • 47
  • 68

3 Answers3

51

It is also possible to set a default host that will be used in all mailers by setting the :host option in the default_url_options hash

in an application_controller.rb add:

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

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

Alternatively, you can pass the request when calling the mailer function from the controller

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

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

montrealmike
  • 11,433
  • 10
  • 64
  • 86
11

UPDATE: use the selected response, since this isn't thread safe.

You can create a default filter like this:

# application_controller.rb
before_filter :mailer_set_url_options

...

def mailer_set_url_options
  ActionMailer::Base.default_url_options[:host] = request.host_with_port
end

(source: http://www.cherpec.com/2009/06/missing-host-to-link-to-please-provide-host-parameter-or-set-default_url_optionshost/)

Diego Plentz
  • 6,760
  • 3
  • 30
  • 31
  • Apparently (and infuriatingly) this isn't allowed anymore. I get this error: `RuntimeError (You can no longer call ActionMailer::Base.default_url_options directly. You need to set config.action_mailer.default_url_options. If you are using ActionMailer standalone, you need to include the routing url_helpers directly.)` – ndbroadbent Mar 10 '11 at 03:19
  • Not sure about that @nathan.f77. I am able to set it with: `ActionMailer::Base.default_url_options = {:host => request.host_with_port}` – SooDesuNe Apr 02 '11 at 13:33
  • @SooDesuNe that's been deprecated now. You can't set it directly anymore. – iwasrobbed Apr 29 '11 at 14:59
  • So what's the solution? It seems to me that, while it's useful to be able to set things in initializers via the config object, there should always be a way to modify the configuration after ActionMailer has been initialized... But this seems to still work for me as is in Rails 3.0.9 so I guess that works for now... – Tyler Rick Jul 21 '11 at 19:52
  • Just wanted to chime in and say even with the newly released rails 3.2, this method works perfectly for me. Using subdomains, this was a damn life saver. Thanks! – Eric Jan 20 '12 at 23:33
  • 1
    Use this solution which is threadsafe: http://stackoverflow.com/questions/2660172/how-do-i-set-default-host-for-url-helpers-in-rails – Doug Sep 15 '15 at 17:20
6

the problem is these are initializers, they are run when the rails stack loads, and not when you call active mailer.

but you don't have to use the default_url, you can just pass the hostname into the url_for/named routes in each of your mailer views. The default just avoids having to do that.

see http://api.rubyonrails.org/classes/ActionMailer/Base.html section on generating urls.

Doon
  • 19,719
  • 3
  • 40
  • 44