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

Dia*_* E. 5 api controller ruby-on-rails autoload

我正在运行 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
Run Code Online (Sandbox Code Playgroud)

这是文件结构:

 - app
  - controllers
   - api
    - v1
     - apples_controller.rb
Run Code Online (Sandbox Code Playgroud)

里面有什么apples_controller.rb

class Api::V1::ApplesController < ApplicationController
   // stuff
end
Run Code Online (Sandbox Code Playgroud)

StackOverflow 上的一些帖子表明此错误可能是由我的控制器文件中的拼写错误引起的,但事实并非如此。或者,有些人提到了 Rails 的区分大小写。但是,如果我试图改变apiv1ApiV1将在routes.rb文件中或在控制器,Rails会扔了一个错误。

我看到一条评论建议应该运行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文件中,但似乎不鼓励这样做

有什么想法吗?我在这里至少看到十几个类似的帖子,但似乎没有真正的具体解决方案?

Jef*_*fel 5

当我简单地将 Rails 升级到 5.2.0 版时,我的旧 Rails 5.1 应用程序代码也发生了同样的 (LoadError) 错误。修复(对我而言)是添加一个缺失的源文件,该文件仅定义了一个子模块(以满足自动加载器)。我将在原始帖子示例的上下文中解释修复。

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

app/controllers/api/v1.rb

module Api
  module V1
  end
end
Run Code Online (Sandbox Code Playgroud)

显然,从 Rails 5.2 开始,自动加载器需要明确定义每个模块命名空间。您可以阅读有关Rails 5.2 常量自动加载的技术细节。

以及对同一问题相关 SO 答案