Flowdock
method

url_for

Importance_5
url_for(options = {}) public

Returns a URL that has been rewritten according to the options hash and the defined routes. (For doing a complete redirect, use redirect_to).

url_for is used to:

All keys given to url_for are forwarded to the Route module, save for the following:

  • :anchor - Specifies the anchor name to be appended to the path. For example, url_for :controller => 'posts', :action => 'show', :id => 10, :anchor => 'comments' will produce "/posts/show/10#comments".
  • :only_path - If true, returns the relative URL (omitting the protocol, host name, and port) (false by default).
  • :trailing_slash - If true, adds a trailing slash, as in "/archive/2005/". Note that this is currently not recommended since it breaks caching.
  • :host - Overrides the default (current) host if provided.
  • :protocol - Overrides the default (current) protocol if provided.
  • :port - Optionally specify the port to connect to.
  • :user - Inline HTTP authentication (only plucked out if :password is also present).
  • :password - Inline HTTP authentication (only plucked out if :user is also present).
  • :skip_relative_url_root - If true, the url is not constructed using the relative_url_root of the request so the path will include the web server relative installation directory.

The URL is generated from the remaining keys in the hash. A URL contains two key parts: the <base> and a query string. Routes composes a query string as the key/value pairs not included in the <base>.

The default Routes setup supports a typical Rails path of "controller/action/id" where action and id are optional, with action defaulting to ‘index’ when not given. Here are some typical url_for statements and their corresponding URLs:

  url_for :controller => 'posts', :action => 'recent'                # => 'proto://host.com/posts/recent'
  url_for :controller => 'posts', :action => 'index'                 # => 'proto://host.com/posts'
  url_for :controller => 'posts', :action => 'index', :port=>'8033'  # => 'proto://host.com:8033/posts'
  url_for :controller => 'posts', :action => 'show', :id => 10       # => 'proto://host.com/posts/show/10'
  url_for :controller => 'posts', :user => 'd', :password => '123'   # => 'proto://d:123@host.com/posts'

When generating a new URL, missing values may be filled in from the current request’s parameters. For example, url_for :action => 'some_action' will retain the current controller, as expected. This behavior extends to other parameters, including :controller, :id, and any other parameters that are placed into a Route’s path.   The URL helpers such as url_for have a limited form of memory: when generating a new URL, they can look for missing values in the current request’s parameters. Routes attempts to guess when a value should and should not be taken from the defaults. There are a few simple rules on how this is performed:

  • If the controller name begins with a slash no defaults are used:
      url_for :controller => '/home'
    

    In particular, a leading slash ensures no namespace is assumed. Thus, while url_for :controller => 'users' may resolve to Admin::UsersController if the current controller lives under that module, url_for :controller => '/users' ensures you link to ::UsersController no matter what.

  • If the controller changes, the action will default to index unless provided

The final rule is applied while the URL is being generated and is best illustrated by an example. Let us consider the route given by map.connect 'people/:last/:first/:action', :action => 'bio', :controller => 'people'.

Suppose that the current URL is "people/hh/david/contacts". Let’s consider a few different cases of URLs which are generated from this page.

  • url_for :action => 'bio' — During the generation of this URL, default values will be used for the first and

last components, and the action shall change. The generated URL will be, "people/hh/david/bio".

  • url_for :first => 'davids-little-brother' This generates the URL ‘people/hh/davids-little-brother’ — note that this URL leaves out the assumed action of ‘bio’.

However, you might ask why the action from the current request, ‘contacts’, isn’t carried over into the new URL. The answer has to do with the order in which the parameters appear in the generated path. In a nutshell, since the value that appears in the slot for :first is not equal to default value for :first we stop using defaults. On its own, this rule can account for much of the typical Rails URL behavior.   Although a convenience, defaults can occasionally get in your way. In some cases a default persists longer than desired. The default may be cleared by adding :name => nil to url_for's options. This is often required when writing form helpers, since the defaults in play may vary greatly depending upon where the helper is used from. The following line will redirect to PostController’s default action, regardless of the page it is displayed on:

  url_for :controller => 'posts', :action => nil

If you explicitly want to create a URL that’s almost the same as the current URL, you can do so using the :overwrite_params options. Say for your posts you have different views for showing and printing them. Then, in the show view, you get the URL for the print view like this

  url_for :overwrite_params => { :action => 'print' }

This takes the current URL as is and only exchanges the action. In contrast, url_for :action => 'print' would have slashed-off the path components after the changed action.

Show source
Register or log in to add new notes.
November 6, 2008
4 thanks

current_url

exact url from browser window:

def current_url
  url_for :only_path=>false,:overwrite_params=>{}
end
January 9, 2009
3 thanks

Adding params to generated url

Whenever you want to append custom parameters to a to be generated url it might be necessary to stop url_for from escaping.

url_for(:action => 'some_action', :custom1 => 'some_value', :custom2 => 'some_value', :escape => false)

If the escape => false option is not passed the generated url contains &amp; instead of the correct &-sign.

March 18, 2009
2 thanks

:format

Just wanted to point out that you can also use the :format option:

url_for :controller=>'posts', :action=>'index', :format=>:xml

Results in:

"http://www.example.com/posts.xml"
March 1, 2011 - (<= v3.0.0)
2 thanks

Using namespaces

If you are using a namespace in your routes.rb, for example:

namespace :admin do
  resources :products
end

then you can:

url_for([:admin, @product])

and:

url_for([:edit, :admin, @product])