Simple Rails Routes Catch-all redirect instead of 404

Like so many people fairly new to Rails, I encountered the situation where a requested page that doesn’t exist generates the dreaded 404 not found message. (the default Rails message doesn’t actually mention ‘404′ and it should, but that’s a different matter)

The simplest, graceful solution I came up with is this:
Create a route in config/routes.rb that redirects to a ‘catcher’ method in a controller. It doesn’t really matter which controller you use. Just make sure it corresponds to the route you write.
In that controller define a method called ‘catcher’ (or whatever jives with you). The catcher method simple populates the flash[:notice] with a message telling the site visitor that the page requested does not exist and then redirects to the home page.

It’s not the most sophisticated solution, but it does work and keeps the visitor at your site rather than being turned away by a cryptic message they may not understand. This way, they’re more likely to continue browsing your site! This is a good thing, because the average, every-day human who browses a web site is completely confused and disappointed by messages like 404, even though most have seen it at some point. Besides that, such messages make your site look bad to those visitors.

Of course this method could be made more comprehensive. You could include in the controller method, ‘catcher’, additional code to log the requested address and redirection. It may seem silly, and you could probably dump most of the log generated, but if you could determine that legitimate requests were coming in often enough for a particular mis-spelling or simply a particular page or url/uri, then you might want to actually create that page, or at least a route for it.

Here’s the code:

In config/routes.rb …

# This is a catch-all for routes that don't exist, visitor is redirected to home page.
ActionController::Routing::Routes.draw do |map|
    map.connect ':controller/:action/:id'
    map.connect '*path', :controller => 'home', :action => 'catcher'
end

In the corresponding controller (in my case, app/controllers/home_controller.rb)…

  def catcher
    flash[:notice] = 'Seems that the page you were looking for does not exist, so you\'ve been redirected here.'
    redirect_to :action => 'index'
  end

1 comment so far ↓

#1 Krotzzz on 12.10.07 at 4:03 pm

It doesn’t prevent you from receiving ‘Unknown Action’ pages when some route matches controller but doesn’t match any action.

Leave a Comment