Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

api - "Unable to autoload constant" Bug in Rails 5.2.0

I'm running a Rails 5.2.0 application. This LoadError always appears on the first request after a reboot or a recompile:

Unable to autoload constant Api::V1::ApplesController, expected /fruits_and_vegetables/app/controllers/api/v1/apples_controller.rb to define it

The pertinent files:

routes.rb

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      get 'apples', to: 'apples#get'
    end
  end
end

Here's the file structure:

 - app
  - controllers
   - api
    - v1
     - apples_controller.rb

What's in apples_controller.rb:

class Api::V1::ApplesController < ApplicationController
   // stuff
end

A few posts on StackOverflow have suggested that this error is likely caused by a typo in my controller file, but that is not the case. Or, some folk have mentioned the case sensitivity of Rails. However, if I try to change api and v1 to Api or V1 in the routes.rb file or in the controller, Rails will throw up an error.

I saw a comment suggesting that one should run rails r 'puts ActiveSupport::Dependencies.autoload_paths', and if I don't see /fruits_and_vegetables/app/controllers/api in the output listing, then add config.autoload_paths << Rails.root.join("app/controllers/api") to my config/application.rb file, but it seems that is discouraged.

Any thoughts? I see at least a dozen similar posts on here, but no real concrete solution it seems?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This same (LoadError) error occurred for my legacy Rails 5.1 application code, when I simply upgraded Rails to version 5.2.0. The fix (for me) was to add a missing source file that solely defines a submodule (to satisfy the autoloader). I will explain the fix in the context of the original post example.

In the original post, the ApplesController is part of the V1 namespace. The problem is, that the V1 submodule is not (explicitly) defined. The solution is to create a file, at the proper (autoload) path, that defines the V1 module:

app/controllers/api/v1.rb

module Api
  module V1
  end
end

Apparently, as of Rails 5.2, the autoloader needs every module namespace to be explicitly defined. You can read the technical details about Rails 5.2 constant autoloading.

And a related SO answer to the same issue.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...