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.