1

I've noticed an unexpected behavior in the Rails Routing dispatcher, and I wonder if this violates the "Principle of Least Surprise".

When defining RESTful routes like in resources :items, only: [:index, :new] we get, as expected, these routings:

  Prefix Verb URI Pattern          Controller#Action
   items GET  /items(.:format)     items#index
new_item GET  /items/new(.:format) items#new

The same should be achieved defining each route by hand, using these two lines:

get '/items' => 'items#index'
get '/items/new' => 'items#new'

Now, the first line of the two is exactly the same, infact if you try to define both resources :items, only: :index and get '/items' => 'items#index' one Named Route get "masked" by the other:

Prefix Verb URI Pattern      Controller#Action
 items GET  /items(.:format) items#index
       GET  /items(.:format) items#index

but the second line gives another result: items_new GET /items/new(.:format) items#new.

Try to define both ways, and you get two Named Route for the same URI:

   Prefix Verb URI Pattern          Controller#Action
 new_item GET  /items/new(.:format) items#new
items_new GET  /items/new(.:format) items#new

So why does the helper method change? Moreover when defining each route you don't even get a Named Route for the edit and show actions (try it by yourself).

Shouldn't the keyword resources be just a shortcut to avoid declaring separate routes for index, show, new, edit, create, update and destroy actions (as it's stated in the doc)?

Claudio Floreani
  • 2,441
  • 28
  • 34
  • It looks like it is starting at the right and working its way left underscoring `/`. If you want to specify the name just do `get 'items/new', as: 'new_items'` or whatever you want the named path to be – CWitty Dec 04 '15 at 22:39
  • Sure, that will work. However the question is not about how to make it work, instead it's: "is it something wrong going on here?" Take the example of defining both `resources :items` and trying to declare `get '/items/new' => 'items#new', as: 'new_item'`: rake would prevent it, raising: _ArgumentError: Invalid route name, already in use: 'new_item' You may have defined two routes with the same name using the :as option, or you may be overriding a route already defined by a resource with the same naming._ But `resources :items` and `get '/items' => 'items#index'` bypass the check. – Claudio Floreani Dec 04 '15 at 23:05

0 Answers0