Force absolute URLs for parts of a view or controller

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.


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).

Arne Hartherz Over 11 years ago