Sunday, April 26, 2009

Rails route sequence

For a large RESTful rails project routes can become very complicated and a single controller can be accessed under different resources.

In rails 2.3.2 route sequence is important. Let me give a scenario,

map.resources :shippers, :shallow => true do |shipper|
 shipper.resources :jobs, :member => {:publish => :put} do |job|
 end
end

map.resources :jobs, :collection => {:open_jobs => :get}

This will generate routes as follows(by running rake routes)

job             GET    /jobs/:id(.:format)          {:action=>"show", :controller=>"jobs"}
open_jobs_jobs  GET    /jobs/open_jobs(.:format)    {:action=>"open_jobs", :controller=>"jobs"}

As in route.rb file /job/:id route path is defined first, when you will hit /jobs/open_jobs you will be mapped to {:action=>"show", :controller=>"jobs",:id=>"open_jobs"}

Then when I moved the open_job route definition up before the job resource under shipper, and it worked.

And now /jobs/open_jobs was mapped to {:action=>"open_jobs", :controller=>"jobs"}. So the resource definition is now like,

map.resources :jobs, :collection => {:open_jobs => :get}

map.resources :shippers, :shallow => true do |shipper|
 shipper.resources :jobs, :member => {:publish => :put} do |job|
 end
end

Reordering the sequence resolved that routing issue.

No comments: