Recipe 4.8. Generating URLs Dynamically


Problem

There are many places in your code where you supply URLs to Rails methods that link to other parts of your application. You don't want to lose the flexibility Rails' Routes provide by hardcoding URL strings throughout your application, especially if you decide to change how routing works later. You want to generate URLs within your application based on the same rules that Routes uses to translate URL requests.

Solution

Use Action Controller's url_for method to create URLs programmatically.

Discussion

Let's say your default route (as defined in config/routes.rb) is as follows:

map.connect ':controller/:action/:id'

Then a call to url_for, such as:

url_for :controller => "gallery", :action => "view", :id => 4

produces the URL http://railsurl.com/gallery/view/4, which is handled by the default route. If you don't specify the controller, url_for assumes you want the current controller (the controller to which Rails delegated the current HTTP request).

This default behavior is useful because you're often calling url_for to create a URL for another action in the current controller.

The same default behavior applies to the action and the ID: if you do not specify new ones, url_for defaults to the current one. Thus, for any of the components of the URL that you don't explicitly specify, Rails attempts to use values from the current request to construct a possible route mapping.

As soon as url_for finds one component that is different from the current request, it essentially slashes off all components to the right of it in the URL and no longer uses them as defaults. So, if you specify a different controller that of the current request, then neither the action nor any of the other parts of the current URL will be used to construct the new URL.

If the specified controller name begins with a slash, no defaults are used. If the controller changes, the action defaults to 'index' unless you specify a new one.

How the defaults work can get a little complicated, but url_for is usually intuitive. If you're having trouble with unpredictable defaults, you can render the generated URL with render_text temporarily:

render_text url_for :controller => "gallery", :action => "view", :id => 4

If you want to replace certain parts of the current URL without affecting any of the other parts of it, use the :overwrite_params option. For instance, if you want to change the current action to 'print', but keep the controller and the ID the same, use:

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

This takes the current URL, replaces only the :action, and returns it as the new URL.

See Also

  • Section 4.3"




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net