Rails 5.2.0中的“无法自动加载常量”错误

问题描述

我正在运行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文件或控制器中将v1Api更改为V1routes.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)错误。解决方法(对我而言)是添加一个缺少的源文件,该文件仅定义了一个子模块(以满足自动加载器的要求)。我将在原始帖子示例的上下文中解释此修复程序。

在原始帖子中,ApplesControllerV1名称空间的一部分。问题是V1子模块未(明确)定义。解决方案是在正确的(自动加载)路径下创建一个文件,该文件定义V1模块:

app/controllers/api/v1.rb

module Api
  module V1
  end
end

显然,从Rails 5.2开始,自动加载器需要显式定义每个模块名称空间。您可以阅读有关Rails 5.2 constant autoloading的技术详细信息。

还有一个related SO answer to the same issue

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...