Make ActionMailer use the current request host and protocol for URL generation
When you generate a URL in a mailer view, ActionMailer will raise an error unless you previously configured it which hostname to use. Configuring the correct hostname is quite annoying when you have multiple deployment targets with different hostnames, e.g. a staging server and a production server.
Using the hack below you don't need to configure a default hostname for your mailers. They will always use the hostname for the current request:
Copyclass ApplicationController < ActionController::Base before_filter :make_action_mailer_use_request_host_and_protocol private def make_action_mailer_use_request_host_and_protocol ActionMailer::Base.default_url_options[:protocol] = request.protocol ActionMailer::Base.default_url_options[:host] = request.host_with_port end end
(If your application server talks only HTTP and relies on the web server for SSL, and if the web server is setting a special HTTPS forwarding header, Rails recognizes that a request originally was on HTTPS and will return the correct protocol.)
With ActiveJob
When you are using ActiveJob to deliver your emails, the above does not help. There is no request context when asynchronously delivering mails.
You need to set the host statically in the respective environment files:
Copy# config/environments/production.rb config.action_mailer.default_url_options = { host: 'www.example.com' } # config/environments/staging.rb config.action_mailer.default_url_options = { host: 'staging.example.com' } # config/application.rb as fallback/default config.action_mailer.default_url_options = { host: 'localhost' }
After you configure ActionMailer defaults like this, you no longer need the before_filter
above.
By refactoring problematic code and creating automated tests, makandra can vastly improve the maintainability of your Rails application.