Rails 2.1 nested routes and complex nestings

Written by admin

Topics: Rails, Ruby

The new Rails routing has nice support for nested reources. And, I think it handles just enough nesting. Any more support, and it’s possible to go overboard and write ugly code.

For example, here is what Rails now supports for nested routing syntax:

1
2
3
4
5
  # Simple parent child association
  map.resources :user, :has_many => :posts
 
  # A parent with many types of children
  map.resources :posts, :has_many => [:comments, :trackbacks, :pingbacks ]

Nice. That is prefectly terse and descriptive, without being too clever.

There has been some debate and consternation over why a complicated multi-nested resource can’t be set up this way. For example, if I am building a project management tool, why can’t I do this?

1
2
map.resources :projects, 
  :has_many => [ :releases,  :milestones => [:tasks, {:features => :tasks}] } ]

That is, a project has many releases AND milestones, and in turn milestones have many tasks and features. And, features can also have tasks.

That’s complicated, and too much cleveness to jam into one statement. I think Rails 2.0.2 / 2.1 has it right in making you write that routing rule like this:

1
2
3
4
5
6
7
8
9
  map.resources :projects do |project|
    project.resources :releases
    project.resources :milestones do |milestone| 
      milestone.resources :tasks
      milestone.resources :features do |feature|
        feature.resources :tasks
      end
    end
  end

I hear a crowd of people clamoring for the uber-terse syntax outlined in the second listing. I think that’s a bad idea. It encourages hard-to-follow, obfuscated code.

When you have to do something complicated, it’s worth taking a few extra lines to make it clear to the next programmer.