Ruby 在使用 Rails 创建 API 框架时,开发模式总是报以下错误,总是某几个 controller 加载失败,有哪位大神知道这是什么情况,原生的怎么还没有 grape 稳定呢?

tianrui_ruby · 2022年03月19日 · 最后由 nine 回复于 2022年03月22日 · 500 次阅读

Unable to autoload constant Api::V1::Com::OptionsController, expected /mnt/workspaces/rails_projects/reviewservice/app/controllers/api/v1/com/options_controller.rb to define it

拉踩无助于获得问题答案。

错误信息就是答案

Unable to autoload constant Api::V1::Com::OptionsController, expected /mnt/workspaces/rails_projects/reviewservice/app/controllers/api/v1/com/options_controller.rb to define it

翻译:不能自动加载常量 Api::V1::Com::OptionsController,期望在 /mnt/workspaces/rails_projects/reviewservice/app/controllers/api/v1/com/options_controller.rb 中去定义这个常量。

类名与文件层次不对应

文件层次没有发现问题,而且在生产模式是正常的。如果在 development.rb 中设置 eager_load=true,就可以正常!!!

tianrui_ruby 回复

那就需要更多的信息了,坑可能在其他地方。rails 的常量自动加载机制已经变过几次了。随手试了下,这点代码信息在 rails 6 上没有复现问题。

我用的 rails5,我在查查问题,感谢您的回复

Rails 6 之前的 loader 在一些设置不对的情况下会有些坑,主要是报错信息跟实际问题不相符。所以才有了新的 zeitwerk loader。zeitwerk 对文件名/常量名约束的更严格,报错信息也更明确。

不方便用 Zeitwerk loader 的话先检查一下项目 autoload path 设置的有没有问题,再从错误堆栈找线索。sping stop 也能暂时缓解一下。

7 楼 已删除

把文件都放在 WSL 里面试试看。

tianrui_ruby 回复

顺便提一句,在定义类时,rails 不提倡使用“限定常量”的形式,而是使用“相对常量”的形式,否则对于 classic 的 autoloader,有时会产生诡异的类加载错误。因此 class Api::V1::Com::OptionsController 最好能写成

module Api::V1::Com
  class OptionsContoller < Api::V1::Com::BaseController
  end
end

对于 Zeitwerk 的 autoloader,这两种写法没有区别

首先要排查 Spring 的问题

bin/spring stop 

😂

1 你把 Com 改个别的名试试

2 在 boot.rb 里面加入以下代码试一下

p Api::V1::Com::OptionsController
需要 登录 后方可回复, 如果你还没有账号请 注册新账号