This feature was released in: Rails v2.2.1
Just added to Edge Rails is the ability to exclude and include the default generated routes in your mapping configuration. Previously, map.resources :articles would generate routes to all seven default actions on the ArticlesController (index, create, new, edit, show, update, destroy). You can now tell your routes configuration to only generate a subset of those actions, or to exclude a subset of those actions:
1 2 3 4 5 6 7 8 |
# Only generate the :index route of articles map.resources :articles, :only => :index # Generate all but the destroy route of articles map.resources :articles, :except => :destroy # Only generate the non-modifying routes of articles map.resources :articles, :only => [:index, :show] |
Note that you can use the :all and :none values to denote all or none of the default routes.
1 2 3 4 5 |
# Don't generate any default article routes, just the approve route map.resources :articles, :except => :all, :member => { :approve => :put } # Same map.resources :articles, :only => :none, :member => { :approve => :put } |
You should also note that these options will be inherited by nested resources that don’t override them. For instance, in this example, comments would only have the :index and :show routes exposed:
1 2 3 4 5 |
# Because comments are nested within articles, they too will only # have the index and show routes generated. map.resources :articles, :only => [:index, :show] do |article| article.resources :comments end |
Specifying either an :except or :only option in a nested resource will override its parent resource’s options. E.g. this routing will result in comments having all actions but :show routed:
1 2 3 4 5 |
map.resources :articles, :only => [:index, :show] do |article| # My :except option overrides my parent resources :only article.resources :comments, :except => :show end |
The motivation behind this feature is that complex routing consumes a lot of memory. So eliminating unnecessary and unused routes can significantly reduce your memory consumption. The holy grail of this, however, will be when you can specify which routes should be formatted (json, xml etc…) as this is essentially doubling the number of default routes when very rarely does every call need to be API-accessible.
tags: ruby, rubyonrails

I really like the idea of this feature, but I think the way inheritance works is very unintuitive. I think I’ll end up avoiding this feature when nesting routes, which is disappointing.
Is there any option here to exclude the automatic generation of (often times unnecessary) formatted routes?
Joe: I’ll see if I can fix it in a subsequent patch. It’s basically a bug.
Jeff: that was originally going to be part of this feature, but it’s hard to come up with a configuration syntax that isn’t dreadful. In fact there is another patch on Lighthouse to solve the formatted route problem by removing them altogether and just allowing the regular routes to take an optional :format parameter. Seems like the smart way to go.
@Joe – I agree. I had to run through a few unit tests on my end to make sure that was in fact the way it’s implemented as I didn’t find it intuitive either.
@Tom – great to hear that a patch is coming! I’ll look for it an update the post when it comes out.
There are performance benefit using these routing options? Why should i use these? Thanks.
@Andrea: without these options, map.resources generates routes to all 7 default CRUD actions for each resource, which might be undesirable because a) every route uses more memory, b) your route map (rake routes) gets large and unhelpful, and c) you need extra code in your controller actions if you want to make them unavailable for some resources (e.g. to allow create for /users/1/comments but not for /comments).
If none of those issues bother you then you can ignore this feature!
This patch makes so much sense!
This is a case that claims for it: I’ve got a public and a Admin interface. I want Rails’ RESTful URLs in both, but I don’t need most of the PUTs and POSTs in the public area.
Brilliant!
Oh, finally, huzzah. Another use case: I enjoy mapping both `map.resources :users’ and `map.resource :profile’ to UsersController, but I prefer that only certain actions are enabled for each mapping.
I see this as another evolutionary step away from the old /:controller/:action/:id mindset.
NB there’s a fix for the inheritance problem on http://rails.lighthouseapp.com/projects/8994/tickets/1215—it hasn’t been committed yet, but it should be soon. Sorry for the inconvenience.
Highly desired feature. I was depending on Ryan Bates’ nifty_scaffold to achieve part of this. But nifty_scaffold removed only the unused actions in the controller. I couldn’t do anything for the unused routes generated from the routing engine.
Andrea: If you define only actions that you actually use you’ll see some memory saving (especially in larger projects). It will be faster as well.
What about adding the option not to create formatted_routes if not needed / This would save some memory as well (especially in large projects) ?
I’ve updated the post with the new routing inheritance update which essentially removes the fact that
:exceptand:onlywere originally inheritable in nested resources. The original inheritance was unintuitive.Ryan,
Thanks for the update, but it’s not correct: the options are still inherited, it’s just that it now works right!
Crap, one of these days I’ll get it right. Ok, I’ve updated it now and ran through a couple of tests on my end to make sure I got the intricacies of the inheritance functionality. Thanks, Tom!
Thanks guys for the infos, and thanks Ryan for the article :)
Is this in rails 2.2 rc2 or in the 3.0 branch?
Ah, I see, its in rails 2.2 rc2, which is great for me, but that is suprising though since there is supposed to be a policy of “no new features”.
Thanks guys for the infos, and thanks Ryan for the article :)
I can’t wait to upgrade to Rails 2.2! This feature is going to save me so much memory.