add support for selective resource routes

I've created patch which adds support for specifying a subset of named routes to create when mapping verb-oriented controllers for collections of resources (see http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/838).

You can specify which routes to add using :only and/or :except options with array values containing symbols of :collection, :new, :member and :associations.

This is especially useful for creating nested routes, so that the redundant parent ids are not required for routes containing explicit ids.

For example...

    map.resources :posts do |post|       post.resources :comments, :only => [ :collection, :new ]     end     map.resources :comments, :except => [ :collection, :new ]

The generated routes would nest the collection and new record routes for comment resources within posts...

e.g. GET /posts/1/comments or POST /posts/1/comments

However, the routes with explicit ids would not require the post_id...

e.g. GET /comments/2 instead of GET /posts/1/comments/2

This really helps to clean up urls when nesting resources more than once.

For example, instead of:

  map.resources :projects do |project|     project.resources :milestones do |milestone|       milestone.resources :features do |feature|         feature.resources :tasks       end     end   end

You could use:

  map.resources :projects do |project|     project.resources :milestones, :only => [ :collection, :new ]   end   map.resources :milestones, :except => [ :collection, :new ] do | milestone>     milestone.resources :features, :only => [ :collection, :new ]   end   map.resources :features, :except => [ :collection, :new ] do | feature>     feature.resources :tasks, :only =>[ :collection, :new ]   end   map.resouces :tasks, :except => [ :collection, :new ]

This would result in the ability to simply access:

  /features/72/tasks

Instead of:

  /projects/13/milestones/16/features/72/tasks

For example...

map\.resources :posts do |post|
  post\.resources :comments, :only => \[ :collection, :new \]
end
map\.resources :comments, :except => \[ :collection, :new \]

I don't see how this is necessary? Even without :only and :except, you'll still get what you want. Just by mapping comments inside posts and outside, you'll get routes for both /comments and /post/1/comments defined. And you'll be free to access whichever you need for the case in point. Even the generating routes are disambiguated with post_comment_url and comment_url.

So I don't see how this adds anything except slightly cut down on the number of routes. But that doesn't seem worth the API overhead of adding :only/:except to me.

Thanks for the feedback David.

So I don't see how this adds anything except slightly cut down on the number of routes. But that doesn't seem worth the API overhead of adding :only/:except to me.

Yeah, I didn't like the API overhead of :only/:except, but it was all that made sense to me at the time... upon further reflection this his led to an alternate proposal in the lighthouse ticket (http:// rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/838)...

    map.resources :posts, :shallow => true do |post|       post.resources :comments     end

See the ticket for more complete example and the preceding discussion.

Cheers.

Yeah, I didn't like the API overhead of :only/:except, but it was all that made sense to me at the time... upon further reflection this his led to an alternate proposal in the lighthouse ticket (http:// rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/838)...

map\.resources :posts, :shallow => true do |post|
  post\.resources :comments
end

See the ticket for more complete example and the preceding discussion.

Shallow is a great way of describing it. Neat encapsulation of the pattern. How does the named routes look, though? I take you'd get post_comments_url(post) and comment_url(comment), right?

Shallow is a great way of describing it. Neat encapsulation of the pattern. How does the named routes look, though? I take you'd get post_comments_url(post) and comment_url(comment), right?

Thanks.

Yes, that's exactly right for the named routes.