bploetz / versionist

A plugin for versioning Rails based RESTful APIs.
MIT License
972 stars 51 forks source link

Invalid route name when using path parameter #69

Closed cheshire137 closed 9 years ago

cheshire137 commented 9 years ago

I want routes like /api/1/my_controller, so I used the following:

scope '/api' do
  api_version(module: 'V1', path: {value: '1'}, default: true,
              defaults: {format: :json}) do

However, this causes the following error:

% rake routes
rake aborted!
ArgumentError: Invalid route name: '1_localization'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/route_set.rb:427:in `add_route'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/mapper.rb:1495:in `add_route'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/mapper.rb:1472:in `decomposed_match'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/mapper.rb:1453:in `block in match'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/mapper.rb:1443:in `each'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/mapper.rb:1443:in `match'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/mapper.rb:636:in `map_method'
/Users/me/.rvm/gems/ruby-2.1.3/gems/actionpack-4.1.8/lib/action_dispatch/routing/mapper.rb:597:in `get'
/Users/me/code/my-app/config/routes.rb:4:in `block (3 levels) in <top (required)>'

How can I have a path parameter that starts with a number?

bploetz commented 9 years ago

@moneypenny what do you have within the api_version block there?

bploetz commented 9 years ago

For the sake of completeness, this works for me locally using a standard resources within the api_version:

Rails.application.routes.draw do
  scope '/api' do
    api_version(module: 'V1', path: {value: '1'}, default: true, defaults: {format: :json}) do
      resources :foos
    end
  end
[bploetz:~/workspace/versionist-test-apis/test-api-rails41]  bundle exec rake routes
          Prefix Verb   URI Pattern                    Controller#Action
                 GET    /api/1/foos(.:format)          v1/foos#index {:format=>:json}
                 POST   /api/1/foos(.:format)          v1/foos#create {:format=>:json}
       new_1_foo GET    /api/1/foos/new(.:format)      v1/foos#new {:format=>:json}
      edit_1_foo GET    /api/1/foos/:id/edit(.:format) v1/foos#edit {:format=>:json}
                 GET    /api/1/foos/:id(.:format)      v1/foos#show {:format=>:json}
                 PATCH  /api/1/foos/:id(.:format)      v1/foos#update {:format=>:json}
                 PUT    /api/1/foos/:id(.:format)      v1/foos#update {:format=>:json}
                 DELETE /api/1/foos/:id(.:format)      v1/foos#destroy {:format=>:json}
    default_foos GET    /api/foos(.:format)            v1/foos#index {:format=>:json}
                 POST   /api/foos(.:format)            v1/foos#create {:format=>:json}
 new_default_foo GET    /api/foos/new(.:format)        v1/foos#new {:format=>:json}
edit_default_foo GET    /api/foos/:id/edit(.:format)   v1/foos#edit {:format=>:json}
     default_foo GET    /api/foos/:id(.:format)        v1/foos#show {:format=>:json}
                 PATCH  /api/foos/:id(.:format)        v1/foos#update {:format=>:json}
                 PUT    /api/foos/:id(.:format)        v1/foos#update {:format=>:json}
                 DELETE /api/foos/:id(.:format)        v1/foos#destroy {:format=>:json}
cheshire137 commented 9 years ago

Interesting. I'm using version 1.4.0 of the gem. I bet the problem was I have a mixture of resources like you show but also get 'localizations/:lang', to: 'localization#show', as: :localization. I'll see if I can omit the as and get rid of the error.

I also discovered that removing the scope '/api' and instead doing just api_version(module: 'V1', path: {value: 'api/1'}, default: true, defaults: {format: :json}) do also works and gives me the URL I want, so I may stick with that.

bploetz commented 9 years ago

@moneypenny yeah, if I add that get 'localizations/:lang', to: 'localization#show', as: :localization line within my api_version I get the same error. The line in action_dispatch it's barfing on is this:

https://github.com/rails/rails/blob/4-1-stable/actionpack/lib/action_dispatch/routing/route_set.rb#L427

As you can see, the route name has to start with an underscore or a lower case letter. Omitting the :as option gets rid of the problem (but obviously gives you a different route name):

[bploetz:~/workspace/versionist-test-apis/test-api-rails41]  bundle exec rake routes
          Prefix Verb   URI Pattern                          Controller#Action
                 GET    /api/1/localizations/:lang(.:format) v1/localization#show {:format=>:json}
         default GET    /api/localizations/:lang(.:format)   v1/localization#show {:format=>:json}
cheshire137 commented 9 years ago

I'm fine closing this issue, I have a couple workarounds. Thanks!

bploetz commented 9 years ago

Cool, thanks @moneypenny