Dev*_*v V 1 ruby ruby-on-rails zeitwerk ruby-on-rails-7
我最近将应用程序从 Rails 6 升级到 7,由于 zeitwerk 命名约定,我面临一个问题。我有一个要自动加载的以下文件:
app/models/dw/hospital.rb
module DW
class Hospital < DataWarehouse
def self.columns
super.reject{|column| column.name == 'tableau_user' }
end
end
end
Run Code Online (Sandbox Code Playgroud)
我尝试通过在文件中添加以下行来自动加载此文件application.rb:
config.autoload_once_paths << 'app/models/dw'
Run Code Online (Sandbox Code Playgroud)
但是当我启动服务器时,出现以下错误:
expected file app/models/dw/hospital.rb to define constant Hospital, but didn't (Zeitwerk::NameError)
Run Code Online (Sandbox Code Playgroud)
我不确定为什么会抛出这样的错误,因为该常量已经定义了。我怀疑这是因为我在课程之前定义了模块。如果有人如何解决这个问题,请告诉我。我已经被困在这个问题太久了。
因为您已添加app/models/dw到自动加载路径,所以您必须定义Hospital,但您的定义是命名空间的DW::Hospital。您不需要触摸自动加载配置,app/models它已经在autoload_paths:
>> ActiveSupport::Dependencies.autoload_paths
=>
...
"/home/alex/code/stackoverflow/app/jobs",
"/home/alex/code/stackoverflow/app/mailers",
"/home/alex/code/stackoverflow/app/models", # <======
...
Run Code Online (Sandbox Code Playgroud)
这些就是所谓的根目录。这意味着文件结构必须app/models与模块/类名称相对应。
因此,如果您dw/hospital.rb在任何根目录中有Dw::Hospital,则必须定义您已经定义的。您还必须注意词形变化,应该如此Dw,除非您有首字母缩略词词形变化规则或zeitwerk 词形变化:
>> "dw".camelize
=> "Dw"
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym "DW"
end
>> "dw".camelize
=> "DW"
Run Code Online (Sandbox Code Playgroud)
如果你必须嵌套根目录,你应该有一个很好的理由:
>> "dw".camelize
=> "Dw"
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym "DW"
end
>> "dw".camelize
=> "DW"
Run Code Online (Sandbox Code Playgroud)
但正如 Xavier 在评论中提到的,没有必要进行此配置。使用默认配置,不要使您的设置变得不必要的复杂化。
| 归档时间: |
|
| 查看次数: |
2628 次 |
| 最近记录: |