I’m trying to setup a subdirectory in my Rails 3.2.3 app to service API requests at: http://example.com/api
I have created a directory like: app/controllers/api/
and I’m following the standard convention for implementing the namespaced controllers:
module Api
class GroupsController < ApplicationController
# RESTful verbs implemented here
end
end
I’ve setup a namespaced route like this:
namespace :api, defaults: {format: 'json'} do
resources :groups
end
However requests to http://example.com/api/groups.json result in the following exception:
ActionController::RoutingError (wrong constant name groups):
app/controllers/api/groups_controller.rb:2:in `<module:Api>'
app/controllers/api/groups_controller.rb:1:in `<top (required)>'
As you can see, it appears that the name “groups” here isn’t valid because it’s lowercase. I have no idea where this is coming from though.
I have read in a few places that a version of the right-aws gem was breaking the String#camelize method and causing similar errors. However I have confirmed that this gem is not present in my Rails application’s stack.
Been slamming my head against this for some time. Has anyone else ever hit this problem?
EDIT: pasted output from $ rake routes:
root / welcome#index
api_groups GET /api/groups(.:format) api/groups#index {:format=>"json"}
POST /api/groups(.:format) api/groups#create {:format=>"json"}
new_api_group GET /api/groups/new(.:format) api/groups#new {:format=>"json"}
edit_api_group GET /api/groups/:id/edit(.:format) api/groups#edit {:format=>"json"}
api_group GET /api/groups/:id(.:format) api/groups#show {:format=>"json"}
PUT /api/groups/:id(.:format) api/groups#update {:format=>"json"}
DELETE /api/groups/:id(.:format) api/groups#destroy {:format=>"json"}
So the underlying cause of this was some code from an internal gem conflicting with the routing/namespacing of Rails.
However, the code in this gem was copied/pasted from an older version of Rails, so other people may hit this same issue.
The root cause was the gem had over-ridden the String#constantize inflection method that Rails extends on the String class. The version of the method this gem copied does not play well with the latest version of Rails and recent versions of Ruby.
So, the result was that
"#{controller_name}".constantizereturned a camelCase name, but the first character was lowercase.Solution is to update this String#constantize method in the gem to match the latest version from Rails core, or to simply remove/rename that method within the gem’s codebase.