Read more

Force absolute URLs for parts of a view or controller

Arne Hartherz
November 27, 2012Software engineer at makandra GmbH

You know that you can force absolute URLs throughout a response. Now you want to modify URLs similarly, but only in parts of a view (or controller) logic. Here is how.


Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

Note: this has only been tested on a Rails 2 application. It should work similarly for Rails 3.


Put this into your ApplicationController:

def rewrite_options(*args)
  options = super
  options.merge!(:only_path => false) if @with_full_urls
  options
end

def with_full_urls(options = {}, &block)
  old_with_full_urls = @with_full_urls
  @with_full_urls = true if options.fetch(:if, true)
  @with_full_urls = false if options.fetch(:disable, false)
  yield
ensure
  @with_full_urls = old_with_full_urls
end
helper_method :with_full_urls

def without_full_urls(&block)
  with_full_urls(:disable => true, &block)
end
helper_method :without_full_urls

Now you can use with_full_urls in views, helpers or controllers and Rails methods like url_for will generate "full" URLs that have a protocol and hostname. You may use without_full_urls to temporarily switch it off again.

If you also want to force a specific host that is defined in your application as HOST, simply adjust the above to say:

  options.merge!(:only_path => false, :host => HOST) if @with_full_urls

Note that while this is enough for links in your HTML, it does not affect asset paths like the host enforcement trait does. So it's not enough to use this in an around_filter (just in case you were wondering).

Posted by Arne Hartherz to makandra dev (2012-11-27 17:43)