Tatva-Artha

meaning of "it"

Environment specific routing in rails

without comments

For better application support, it is usually nice to build features that allow us query live system information inside a webapp. Such information can obviously be password protected. However, recently I ended up in a situation where client wasn’t ready to reveal such information in production environment. So, I had to disable this functionality in production.

In rails, this means disabling certain routes for production environment. It isn’t a major problem since you can guard your route declarations using RAILS_ENV value. However, I ran into a few quirks that I had to resolve.

In my case, my debug resources were available at URI ‘/debug’ (that went to DebugController as is usually the case). My routes.rb contained

ActionController::Routing::Routes.draw do |map|
  ...
  map.resources :debug
  ...
end

This obviously allows /debug for all environments. For disabling it in production, I did this:

  map.resources :debug unless RAILS_ENV == 'production'

This didn’t work. The reason was my routes still had the default routes:

ActionController::Routing::Routes.draw do |map|
  ...
  map.resources :debug
  ...
  # Install the default routes as the lowest priority.
  # Note: These default routes make all actions in every controller accessible via GET requests. You should
  # consider removing or commenting them out if you're using named routes and resources.
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end

As the comments suggest, these routes should ideally be removed in RESTful app. However, in my project, that may mean several broken routes. That was more then what I wanted to handle at this time. So, my options were to add another route for production before these default routes that would send the user to some default message with proper flash message. Here is what I ended up with:

  map.debug "debug", :controller => "debug", :action => "noop" if RAILS_ENV == 'production'
  map.resources :debug unless RAILS_ENV == 'production'

and

class DebugController < ApplicationController
  ...
  def noop
    flash[:message] = "Debug information is not available in this environment"
    redirect_to root_url
  end
end

With this, all /debug/* got sent to action “noop” in production environment. I could test routes using “rake routes” command by setting environment variable RAILS_ENV to “development” vs. “production”.

$ export RAILS_ENV=development
$ rake routes | grep debug
                 debug_index GET    /debug(.:format)                                           {:controller=>"debug", :action=>"index"}
                             POST   /debug(.:format)                                           {:controller=>"debug", :action=>"create"}
                   new_debug GET    /debug/new(.:format)                                       {:controller=>"debug", :action=>"new"}
                  edit_debug GET    /debug/:id/edit(.:format)                                  {:controller=>"debug", :action=>"edit"}
                       debug GET    /debug/:id(.:format)                                       {:controller=>"debug", :action=>"show"}
                             PUT    /debug/:id(.:format)                                       {:controller=>"debug", :action=>"update"}
                             DELETE /debug/:id(.:format)                                       {:controller=>"debug", :action=>"destroy"}
$ export RAILS_ENV=production
$ rake routes | grep debug
                       debug        /debug                                                     {:controller=>"debug", :action=>"noop"}

For TDD, this could be unit tested as described here.

http://www.tatvartha.com/wp-content/plugins/sociofluid/images/digg_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/reddit_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/stumbleupon_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/delicious_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/google_16.png http://www.tatvartha.com/wp-content/plugins/sociofluid/images/twitter_16.png

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

Written by Sharad

September 16th, 2009 at 3:58 pm

Posted in All

Leave a Reply