There are some cases when you want to get a current request absolute URL. Thankfully, Rails got you covered on this one and provides a simple way for that:
request.original_url
This’ll return an absolute full URL including schema, host, port, path, and query string, but without anchor though. The anchor (#section) never reaches your server: the browser keeps it to itself, so Rails has no way to know it.
So, for a request to https://example.com/resource?q=first:
request.original_url # => https://example.com/resource?q=first
request.fullpath # => /resource?q=first
request.path # => /resource
If you only need the scheme and host, for example to build a link back to your own site, use request.base_url. For the request above it returns https://example.com. A non-default port is kept, so a request to http://example.com:3000/resource?q=first gives an original_url of http://example.com:3000/resource?q=first.
Building full URL #
When you need to build a full URL in controller views you can simply use the URL helpers provided by Rails:
post_url(@post)
But it’s not that easy outside the request(controller/view) scope. For example, if you need to build a full URL inside a background job, Rails can’t simply get the host for that from a request, since there’s no request.
To make it work we need two things #
First, include URL helpers.
class MyJob < ApplicationJob
include Rails.application.routes.url_helpers
def perform(user)
user_url(user)
...
end
end
And then, set url options in app configuration:
# config/environments/production.rb
Rails.application.routes.default_url_options[:host] = "example.com"
# And for email views
Rails.application.config.action_mailer.default_url_options = { host: "example.com" }
Without the host, the first user_url call in a job fails with ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true. That error is your sign that this step is missing.
Mailers read their own setting, config.action_mailer.default_url_options, as shown in the Action Mailer guide. Older snippets online set config.action_mailer[:host] instead. On Rails 8.1 that line stops the app from booting with undefined method 'host=' for class ActionMailer::Base, so use the default_url_options form.
If you need to generate URLs for assets (for example images/icons in emails) you’ll need to set asset_host as well:
# Need only if host is other than the one
# that handles requests
config.action_controller.asset_host = 'example.com'
# Required since mailer has no request context
# to get host address from
config.action_mailer.asset_host = 'https://example.com'
The mailer value needs the protocol (https://). A mailer has no request to copy it from, and the Action Mailer guide asks for it explicitly.
On Rails 8.1, with the host configured, both a job and a mailer produce http://example.com/users/42. To get https links, add protocol: "https" to the same default_url_options hash.


