What's New in Edge Rails: :except and :only Routing Options

Posted by ryan
at 9:20 AM on Thursday, November 13, 2008

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 }

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.

The original implementation included inheritance of these options, but that has been reverted. So no more inheritance, you need to specify :except and :only at each resource-level.

tags: ruby, rubyonrails

Comments

Leave a response

  1. Joe FerrisNovember 13, 2008 @ 10:37 AM

    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.

  2. JeffNovember 13, 2008 @ 11:35 AM

    Is there any option here to exclude the automatic generation of (often times unnecessary) formatted routes?

  3. Tom StuartNovember 13, 2008 @ 12:17 PM

    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.

  4. Ryan DaigleNovember 13, 2008 @ 03:04 PM

    @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.

  5. AndreaNovember 13, 2008 @ 05:29 PM

    There are performance benefit using these routing options? Why should i use these? Thanks.

  6. Tom StuartNovember 13, 2008 @ 05:52 PM

    @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!

  7. Ismael CelisNovember 13, 2008 @ 06:10 PM

    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!

  8. Lance IvyNovember 13, 2008 @ 07:17 PM

    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.

  9. Tom StuartNovember 14, 2008 @ 04:35 AM

    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.

  10. SubbuNovember 14, 2008 @ 05:02 AM

    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.

  11. hosiawakNovember 14, 2008 @ 05:05 AM

    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) ?

  12. Ryan DaigleNovember 14, 2008 @ 08:02 AM

    I’ve updated the post with the new routing inheritance update which essentially removes the fact that :except and :only were originally inheritable in nested resources. The original inheritance was unintuitive.

  13. Tom StuartNovember 14, 2008 @ 09:25 AM

    Ryan,

    Thanks for the update, but it’s not correct: the options are still inherited, it’s just that it now works right!

  14. Ryan DaigleNovember 14, 2008 @ 09:53 AM

    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!

  15. AndreaNovember 14, 2008 @ 04:10 PM

    Thanks guys for the infos, and thanks Ryan for the article :)

  16. JasonNovember 15, 2008 @ 10:38 PM

    Is this in rails 2.2 rc2 or in the 3.0 branch?

  17. JasonNovember 16, 2008 @ 02:35 AM

    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”.

  18. KundenserviceNovember 17, 2008 @ 12:37 AM

    Thanks guys for the infos, and thanks Ryan for the article :)

  19. AviNovember 18, 2008 @ 01:26 AM

    I can’t wait to upgrade to Rails 2.2! This feature is going to save me so much memory.