Archive | March 2009

A default route gone 404 when it should

UPDATE: This worked for Rails < 2.0, but now you should follow something like this

Rails routes are a critical piece of a rails application. One issue about the routes is that there isn’t a default route for the home page of an application. Typically, one would create a controller and create a route for a default controller and default action. Here is what one of mine looks like:

map.root :controller => 'main', :action => 'home'

There is one problem with this. The url http://domain.com/blah%20blah will go to the main controller and will throw an “no action/ no id given” exception which will result in a 500 error. This is not what you want for SEO or otherwise.

The solution is quite simple, all you have to do is add a method missing to the main controller and add a method missing that logs and renders a real 404 page and http status.

  def method_missing(method, *args)
    logger.warn "action #{method} dos not exist, 404" 
    render :file => File.join(RAILS_ROOT, 'public', '404.html'), :status => 404
  end

There may be better ways to do this, but this is one way around the false 500 errors, especially if your likely to get old inbound links to your site.

Making the Rails Request Profiler and KCacheGrind Play

I have been working on optimizing my companies site after porting over many features. I have been finding the newer rails performance tools including the request profiler to be very helpful in this effort. Ryan Bates put out a great screencast on request profiling that will get you started, but if your app has any complexity, you will find out quickly like I did that the html file gets too large and is not very helpful when it crashes your browser. 😉

Assuming that you have already installed KCacheGrind on your Mac usingfink, you can do the following:

# Open up the request_profiler.rb in the actionpack gem (the code that is used by ./script/performance/request)

mate /Library/Ruby/Gems/1.8/gems/actionpack-2.2.2/lib/action_controller/request_profiler.rb

# Add the following lines of ruby to the show_profile_results method at the bottom.

        File.open "#{RAILS_ROOT}/tmp/profile-call-tree.kcg", 'w' do |file|
           RubyProf::CallTreePrinter.new(results).print(file)
           `kcachegrind #{file.path}` if options[:open]
        end

Now next time you run the request profiler you will see the KCacheGrind open up with the call tree output in it, yeah!

Changing Session Store in Rails

TIP: If you change the sessions store in rails, I would recommend also changing the session_id so your app doesn’t blow up with 500 errors on every request.

I changed the store from cookie based sessions (the default) to memcached based sessions.