我目前正在将一个旧的Rails应用程序迁移到Rails6。
项目中的某些文件似乎与其中定义的类不一致。在运行应用程序的测试时,我没有看到这个错误,但在部署后,我收到了如下错误:
Zeitwerk::NameError: expected file /app/my?_/app/lib/multi_io.rb to define constant MultiIo, but didn't
在之前的SO问题中,我可以找到以下建议:
- Rails 6:Zeitwerk::NameError dos';t从模块集
config.autoloader = :classic
加载类 - 如何在Zeitwerk for Rails6中忽略文件夹?忽略给定的路径
- Rails6微调
config.autoload_path
中的自动加载和Zeitwerk模式
我没有寻找解决方法,所以我更正了引发异常的文件。
我想找到一种程序化的方法来检测所有不一致的路径/类名,而无需在生产模式下运行应用程序。
到目前为止,我想到了三个选择:
- 用于验证自动加载的rake任务(gem不提供(。它存在吗?您会在开发环境中从rails控制台运行一个代码片段吗
- rubocop-cop或其他静态代码分析器。有吗
- 在测试环境中强制加载
在不需要多次迭代/部署的情况下验证代码的建议方法是什么?
提前非常感谢
您可以检查项目与zeitwerk::check
任务的自动加载兼容性:
$ bin/rails zeitwerk:check
Hold on, I am eager loading the application.
All is good!
它练习所有的自动加载路径,并将标记问题,例如由常量名称推断中的更改引起的问题(例如使用缩写词的问题(。除了在升级指南中,该任务似乎没有被广泛宣传或记录。但是,实际上,我有时会使用它来解决项目中经常出现的命名问题(即,类与文件不匹配的地方(。
@rmlockerd在这里的回答中描述了最好的工具之一bin/rails zeitwerk:check
。
我发现其他提供信息的文章有:
- 在Rails中理解Zeitwerk
- 9个提示;帮助您在Rails应用程序
- 关于自动加载的Rails文档
- 关于从Rails 5.2升级到6.0的Rails文档
我所做的过程是运行bin/rails zeitwerk:check
修复一个错误,再次运行它,直到我看到";一切都很好;。之后,我们的规范测试报告了错误。
需要解决的一个常见问题是,如果文件夹不在Rails默认文件结构中,Zeitwerk在自动加载时将无法找到它。我们有一个名为";服务";(app/services
(,需要添加到application.rb文件中的自动加载路径中,如:
config.autoload_paths += %W(#{config.root}/app/services/)
错误:
需要文件
path/file_name.rb
来定义常量FileName
修复:删除引用类定义位置的其他文件中的任何require
或require_relative
(Zeitwerk不需要它们(。
错误(类在子目录的模块中定义(:
名称错误:未初始化常量子文件::ClassName
修复:
另一个S/O答案中有详细说明。每当在子文件夹结构中使用方法时,调用为Folder::SubDirectory::Class.method_call
祝你好运!