I refactored my rails app in a way that for every sub resources i create a controller is the according namespace.
api/v1/app/controller/manager.rb
api/v1/app/controller/manager/user.rb
api/v1/app/controller/manager/controller.rb
api/v1/app/controller/admin.rb
api/v1/app/controller/user.rb
api/v1/app/controller/controller.rb
The class definition of the user resource under the manager namespace looks like this
class Api::V1::Manager::UserController < ApplicationController
This controller is reachable through routes.rb:
resources :manager , only: [:show ] do
resources :user, only: [:index], controller: 'manager/user'
end
which generates
/api/v1/manager/:manager_id/user(.:format) api/v1/manager/manager#index {:format=>"json"}
The models are all under
app/models/manager.rb
app/models/user.rb
When i want to access now the Manager
model inside the api/v1/app/controller/manager/user.rb
controller or in api/v1/app/controller/manager.rb
e.g
class Api::V1::ManagerController < ApplicationController
def index
Manager.find(...)
end
end
class Api::V1::Manager::UserController < ApplicationController
def index
Manager.find(...)
end
end
i get these errors
{"error":"uninitialized constant Api::V1::Manager::UserController::Manager"}%
{"error":"uninitialized constant Api::V1::Manager::Manager"}%
The calls are handled by the correct controllers :
Processing by Api::V1::Manager::UserController#index as JSON
The solution is to use the double colon prefix with the call
`::Manager.find(...)`.
I can use all other models Admin.find(...)
or Controller.first
normally. Only the Manager.find(..)
is not working.
Renaming the namespace to ManagerResource
still produces the same error message.
I would like to be able to group controllers under different namespaces and still access all the models the same way how is that possible?
Update
Created
api/v1/app/controller/api/v1/foo/customer_controller.rb
api/v1/app/controller/api/v1/manager_customer_controller.rb
After starting the server (webrick) all endpoints are working.
Adding Manager.first
- to any controller- or changing something in a file which uses Manager...
returns these errors
`uninitialized constant Api::V1::Foo::UserController::Manager`
`uninitialized constant Api::V1::ManagerUserController::Manager`
`uninitialized constant Api::V1::*any_controller*::Manager`
Restarting the server solves this issue.
I am able to use Controller.first
or any other model in e.g. api/v1/app/controller/controller.rb
.The the server responds well.
Like @Andrey Deineko pointed out i understand now the module and class names should differ.
What i dont understand is why these errors occur only for a specific model when i substract controllers under a namespace which with a different name than the models?
Update II
I removed all manager related namespaces and controllers. So i am back to the original pre-controller-optimization state.
This error occurs only for the Manger
model. In the console Manager.class
shows in any case Class
.
But in the controller this happens:
module Api
module V1
class Manager < Api::ApiBaseController
def index
puts User.class #=> class
puts Manager.class #=> module
puts ::Manager.class #=> class
puts Controller.class #=> class
...
end
end
end
end
class Api::V1::Manager < Api::ApiBaseController
def index
puts User.class #=> class
puts Manager.class #=> {"error":"uninitialized constant Api::V1::ManagerController::Manager"}
puts ::Manager.class
puts Controller.class
...
end
end
when i change the order so that ::Manager
is first everything works as expected and also the classes then match
class Api::V1::Manager < Api::ApiBaseController
def index
puts User.class #=> class
::puts Manager.class #=> class
puts Manager.class #=> class
puts Controller.class #=> class
...
end
end
The namespace Api::V1::...
works for every other controller.