问题描述
我正在运行Rails 5.2.0应用程序。重新启动或重新编译后,此LoadError
总是出现在第一个请求上:
Unable to autoload constant Api::V1::ApplesController,expected /fruits_and_vegetables/app/controllers/api/v1/apples_controller.rb to define it
相关文件:
routes.rb
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
get 'apples',to: 'apples#get'
end
end
end
这是文件结构:
- app
- controllers
- api
- v1
- apples_controller.rb
apples_controller.rb
中的内容:
class Api::V1::ApplesController < ApplicationController
// stuff
end
StackOverflow上的一些帖子表明此错误可能是由于我的控制器文件中的错字引起的,但事实并非如此。或者,有些人提到了Rails的大小写敏感性。但是,如果我尝试在api
文件或控制器中将v1
和Api
更改为V1
或routes.rb
,则Rails会引发错误。
I saw a comment建议一个人应该运行rails r 'puts ActiveSupport::Dependencies.autoload_paths'
,如果我在输出清单中没有看到/fruits_and_vegetables/app/controllers/api
,则将config.autoload_paths << Rails.root.join("app/controllers/api")
添加到我的config/application.rb
文件,但it seems that is discouraged。
有什么想法吗?我在这里至少看到十几个类似的帖子,但是似乎没有真正的具体解决方案?
解决方法
当我简单地将Rails升级到版本5.2.0时,我的旧版Rails 5.1应用程序代码也发生了同样的(LoadError)错误。解决方法(对我而言)是添加一个缺少的源文件,该文件仅定义了一个子模块(以满足自动加载器的要求)。我将在原始帖子示例的上下文中解释此修复程序。
在原始帖子中,ApplesController
是V1
名称空间的一部分。问题是V1
子模块未(明确)定义。解决方案是在正确的(自动加载)路径下创建一个文件,该文件定义V1
模块:
app/controllers/api/v1.rb
module Api
module V1
end
end
显然,从Rails 5.2开始,自动加载器需要显式定义每个模块名称空间。您可以阅读有关Rails 5.2 constant autoloading的技术详细信息。