Catch-All routes in Rails

Sometimes you need a catch-all route in rails to support dynamic applications like Content Management Systems, where all requests that are not matched by an existing route get passed to a controller who can deal with the request.

Add the following to the end of your routes.rb :

map.with_options(:controller => ‘page_engine’) do |site|
site.connect ‘*url’, :action => ‘show_page’
end

If that’s your last route, it means that anything that isn’t recognised by any of the other routes will get routed to that controller/action (page_engine/show_page). It shouldn’t interfere with images/assets because they are served with higher priority than Rails routes. It lets you have any number of forward-slashes.

So if you hit your site with the following URL:

http://localhost:3000/we/really/hate/wcf

The request will be routed to the show_page action in the page_engine controller where you can then access the actual url elements with :

1
2
path = request.path # '/we/really/hate/wcf'
path_elements = request.path.split('/') # ['', 'we', 'really', 'hate', 'wcf']

While this isn’t the type of thing you would do on many Rails projects you certainly will find this useful for projects that have an element of dynamic routing that goes beyond the RESTful style that rails implements, and its especially useful for implementing Content Management Systems.

2 comments

  1. That’s exactly what i was looking for to redirect old urls from a legacy system to new and restful urls.

    Thx a million

  2. Hi Floyd

    Thanks Man, This is what I’m looking for all this time

Leave a comment