Rails 6:Zeitwerk::NameError 不从模块加载类 [英] Rails 6: Zeitwerk::NameError doesn't load class from module
问题描述
我有一个看起来像这样的文件
I have a file which looks like this
#app/services/account/authenticate/base.rb
module Account
module Authenticate
AuthenticateError = Class.new(StandardError)
class Base < ::Account::Base
def self.call(*attrs)
raise NotImplementedError
end
end
end
end
现在当我从 rails c
运行代码时出现错误
Now when I will run the code from rails c
I have an error
> ::Account::Authenticate::AuthenticateError
=> NameError (uninitialized constant Account::Authenticate::AuthenticateError)
> ::Account::Authenticate.constants
=> [:Base, :ViaToken]
所以 rails 没有看到 AuthenticateError 类.但是当我从这个文件夹创建一个嵌套类时,比如
So rails doesn't see AuthenticateError class. But when I will create a nested class from this folder like
=> Account::Authenticate::ViaToken
> ::Account::Authenticate.constants
=> [:Base, :AuthenticateError, :ViaToken]
AuthenticateError 类现在可见
AuthenticateError class is now visible
> ::Account::Authenticate::AuthenticateError
=> Account::Authenticate::AuthenticateError
这个问题的解决方案是创建一个单独的文件authenticate_error.rb,它从一开始就可以工作,但这个解决方案对我来说并不理想.是否有任何解决方案可以预加载所有类或 smth?
The solution for this problem is to create a separate file authenticate_error.rb which will work from the beginning but this solution is not ideal for me. Is there any solution to preload all classes or smth?
(Ruby 2.6 和 Rails 6.0.0.rc2)
(Ruby 2.6 with Rails 6.0.0.rc2)
推荐答案
我在将 Rails 6.0.2 应用程序部署到 Ubuntu 18.04 服务器时遇到了同样的问题.
I experienced this same issue when deploying a Rails 6.0.2 application to an Ubuntu 18.04 server.
无法加载应用程序:Zeitwerk::NameError:预期文件/home/deploy/myapp/app/models/concerns/designation.rb 定义常量 Designation,但没有
Unable to load application: Zeitwerk::NameError: expected file /home/deploy/myapp/app/models/concerns/designation.rb to define constant Designation, but didn't
我发现问题出在 zeitwerk.Zeitwerk 是 Rails 6 中使用的新代码加载器引擎.它旨在成为所有 Rails 6+ 项目的新默认引擎,取代旧的经典引擎.Zeitwerk 提供代码自动加载、预先加载和重新加载的功能.
I found out that the issue was with zeitwerk. Zeitwerk is the new code loader engine used in Rails 6. It’s meant to be the new default for all Rails 6+ projects replacing the old classic engine. Zeitwerk provides the features of code autoloading, eager loading, and reloading.
我是这样解决的:
导航到项目中的 config/application.rb
文件.
Navigate to the config/application.rb
file on your project.
在您的应用程序模块中添加此行以切换到 classic
模式以进行自动加载:
Add this line within your application module to switch to classic
mode for autoloading:
config.autoloader = :classic
这是一个例子:
module MyApp
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 6.0
# Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading
# the framework and any gems in your application.
config.autoloader = :classic
end
end
您可以在这篇文章中阅读有关 zeitwerk 的更多信息:了解 Rails 6 中的 Zeitwerk
You can read up more on zeitwerk in this article: Understanding Zeitwerk in Rails 6
仅此而已.
我希望这会有所帮助
这篇关于Rails 6:Zeitwerk::NameError 不从模块加载类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!