Rails Routes Limitations

May 18, 2006     

One of the first things that really impressed me about Rails when I started digging in last year was the bi-directionality of routes. That is to say, routes not only resolve URLs, but the URL helper methods (url_for, link_to, button_to, etc) use routes to generate the “simplest” URL to a given controller / action / id.

I put “simplest” in quotes because it really means the first matching route. The first matching route is usually, but not always, the shortest. As an example allow me to present the following routes file:

map.connect ':controller/:action/:id'
map.connect ':action', :controller => 'content'

The purpose of this routes configuration is to support the grouping of relatively static pages in a single content controller rather than making dozens of controllers without any code in them. These pages could mostly just be served statically except for dynamic components in the layout.

Using this routes file, a given URI such as “/word” will first look for a controller Word, and then look for an action word in the Content controller (or maybe even just a template word.rhtml). This arrangement results in maximally expressive URLs which are very user-friendly.

The only problem here is with Rails url helpers such as:

<%= url_for :controller => "content", :action => "word" %>

In this case the generated URI will be /content/word which works, but is oh-so-ugly.

Originally I had tried reversing the order of the routes, but this blocks out legitimate controllers. Fundamentally I’m not sure there’s a good solution to this problem at the Rails level. I’ve opted to individually route all the static pages which is a horribly un-railsy solution, but for a small site it seems acceptable.