the*_*ter 7 ruby ruby-on-rails ruby-on-rails-4
我重构了我的rails应用程序,对于我创建控制器的每个子资源都是相应的命名空间.
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
Run Code Online (Sandbox Code Playgroud)
manager命名空间下的用户资源的类定义如下所示
class Api::V1::Manager::UserController < ApplicationController
Run Code Online (Sandbox Code Playgroud)
该控制器可通过routes.rb访问:
resources :manager , only: [:show ] do
resources :user, only: [:index], controller: 'manager/user'
end
Run Code Online (Sandbox Code Playgroud)
产生
/api/v1/manager/:manager_id/user(.:format) api/v1/manager/manager#index {:format=>"json"}
Run Code Online (Sandbox Code Playgroud)
这些模型都在
app/models/manager.rb
app/models/user.rb
Run Code Online (Sandbox Code Playgroud)
当我想现在访问控制器Manager内的模型api/v1/app/controller/manager/user.rb或api/v1/app/controller/manager.rb例如
class Api::V1::ManagerController < ApplicationController
def index
Manager.find(...)
end
end
class Api::V1::Manager::UserController < ApplicationController
def index
Manager.find(...)
end
end
Run Code Online (Sandbox Code Playgroud)
我得到这些错误
{"error":"uninitialized constant Api::V1::Manager::UserController::Manager"}%
{"error":"uninitialized constant Api::V1::Manager::Manager"}%
Run Code Online (Sandbox Code Playgroud)
调用由正确的控制器处理:
Processing by Api::V1::Manager::UserController#index as JSON
Run Code Online (Sandbox Code Playgroud)
解决方案是在调用时使用双冒号前缀
`::Manager.find(...)`.
Run Code Online (Sandbox Code Playgroud)
我可以使用所有其他型号Admin.find(...)或Controller.first正常使用.只有Manager.find(..)不起作用.
重命名命名空间ManagerResource仍会产生相同的错误消息.
我希望能够在不同的命名空间下对控制器进行分组,并且仍然能够以相同的方式访问所有模型吗?
更新
创建
api/v1/app/controller/api/v1/foo/customer_controller.rb
api/v1/app/controller/api/v1/manager_customer_controller.rb
Run Code Online (Sandbox Code Playgroud)
启动服务器(webrick)后,所有端点都正常工作.添加 Manager.first- 到任何控制器 - 或更改使用的文件中的某些内容会Manager...返回这些错误
`uninitialized constant Api::V1::Foo::UserController::Manager`
`uninitialized constant Api::V1::ManagerUserController::Manager`
`uninitialized constant Api::V1::*any_controller*::Manager`
Run Code Online (Sandbox Code Playgroud)
重新启动服务器可以解决此问题.
我可以使用Controller.first或任何其他模型,例如api/v1/app/controller/controller.rb.服务器响应良好.
就像@Andrey Deineko指出的那样我现在理解模块和类名应该有所不同.
我不明白为什么这些错误只发生在特定模型上,当我在一个名称不同于模型的命名空间下减去控制器时?
更新II
我删除了所有经理相关的命名空间和控制器.所以我回到了原来的预控制器优化状态.
仅对Manger模型发生此错误.在Manager.class任何情况下在控制台显示Class.但在控制器中会发生这种情况:
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
Run Code Online (Sandbox Code Playgroud)
当我改变顺序时,::Manager首先一切都按预期工作,然后类匹配
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
Run Code Online (Sandbox Code Playgroud)
命名空间Api::V1::...适用于所有其他控制器.