【发布时间】:2017-01-18 16:39:21
【问题描述】:
我重构了我的 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
manager命名空间下用户资源的类定义是这样的
class Api::V1::Manager::UserController < ApplicationController
这个控制器可以通过 routes.rb 访问:
resources :manager , only: [:show ] do
resources :user, only: [:index], controller: 'manager/user'
end
生成
/api/v1/manager/:manager_id/user(.:format) api/v1/manager/manager#index {:format=>"json"}
模型都在下面
app/models/manager.rb
app/models/user.rb
当我现在想访问 api/v1/app/controller/manager/user.rb 控制器或 api/v1/app/controller/manager.rb 中的 Manager 模型时,例如
class Api::V1::ManagerController < ApplicationController
def index
Manager.find(...)
end
end
class Api::V1::Manager::UserController < ApplicationController
def index
Manager.find(...)
end
end
我收到这些错误
{"error":"uninitialized constant Api::V1::Manager::UserController::Manager"}%
{"error":"uninitialized constant Api::V1::Manager::Manager"}%
调用由正确的控制器处理:
Processing by Api::V1::Manager::UserController#index as JSON
解决方法是在调用中使用双冒号前缀
`::Manager.find(...)`.
我可以正常使用所有其他型号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
启动服务器 (webrick) 后,所有端点都在工作。
将Manager.first 添加到任何控制器或更改使用Manager... 的文件中的某些内容会返回这些错误
`uninitialized constant Api::V1::Foo::UserController::Manager`
`uninitialized constant Api::V1::ManagerUserController::Manager`
`uninitialized constant Api::V1::*any_controller*::Manager`
重启服务器解决了这个问题。
我可以使用Controller.first 或任何其他模型,例如api/v1/app/controller/controller.rb.服务器响应良好。
就像@Andrey Deineko 指出的那样,我现在明白模块和类名应该不同。
我不明白的是,为什么当我在名称与模型不同的命名空间下减去控制器时,这些错误只发生在特定模型上?
更新二
我删除了所有与管理器相关的命名空间和控制器。所以我回到了原来的 pre-controller-optimization 状态。
此错误仅发生在 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
当我更改顺序以使 ::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
命名空间Api::V1::... 适用于所有其他控制器。
【问题讨论】:
-
ManANger字有错误。没事吧? -
啊是的只是一个错字;)
-
可能是Manager模块id与Manager模型冲突,请尝试更改Manager模块名称
-
@arieljuod 是的,将名称从
app/model/manager.rb更改为app/model/manager_foo让我可以使用 `ManagerFoo.find(...) 但我不确定我理解这意味着什么 -
命名空间像模块一样工作,问题似乎是Manager是模棱两可的,你需要告诉Rails你想要什么Manager,我不确定是否有一个包装所有模型的命名空间,我将更改为 Api::V1::ManagerApi:: 或其他东西
标签: ruby-on-rails ruby ruby-on-rails-4