使用Zeitwerk的Rails 6:如何扩展Ruby核心类,例如日期,时间,字符串等

时间:2019-09-23 11:46:32

标签: ruby-on-rails ruby-on-rails-6

我正在将Rails 5.2.2升级到现在具有Zeitwerk的Rails 6.0.0。

以前,我已经扩展了核心的红宝石类,例如this question中所述的Date,Time,String,Float等。使用初始化程序文件来加载lib/core_ext/*文件夹中的所有文件。现在开始启动rails server时,它会错误显示stacktrace的最后一行:

/home/username/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/zeitwerk-2.1.10/lib/zeitwerk/loader.rb:351:in `const_get': uninitialized constant CoreExt::Date (NameError)

不幸的是,Zeitwerk在lib/core_ext/date.rb等引发已定义错误的地方引发了错误(在Rails.autoloaders.log!中使用application.rb时。CoreExt::Date

此后,我将文件直接移动到initializers(以前,我只有一个初始化器目录,其中包含一个文件,该文件从'lib/core_ext/*文件夹中加载了每个文件)。目前,此问题已解决,但我想将core_ext文件夹和文件保留在原来的位置。

我在这里错过了什么?

lib/core_ext/date.rb

class Date
  def to_sap
    strftime('%d.%m.%Y')
  end
end

我曾尝试在CoreExt中显式包装,但这没有帮助。

module CoreExt
  class Date
    def to_sap
      strftime('%d.%m.%Y')
    end
  end
end

2 个答案:

答案 0 :(得分:2)

https://github.com/fxn/zeitwerk#file-structure上说

loader.push_dir(Rails.root.join("app/models"))
loader.push_dir(Rails.root.join("app/controllers"))

Zeitwerk作者:https://github.com/rails/rails/issues/37835#issuecomment-560563560

由于Rails 3,lib文件夹不属于自动加载路径。如果要自动加载,建议使用@pixeltrix。 否则,lib属于$ LOAD_PATH,您可以在该目录中需要文件。

我们可以调用push_dir来加载lib子目录。我的解决方案:

# config/initializers/zeitwerk.rb

Rails.autoloaders.main.push_dir(Rails.root.join('lib'))

# config/application.rb

  ...
  config.autoload_paths += [
    Rails.root.join('lib')
  ]

然后CoreExt::Date可以自动加载。

答案 1 :(得分:0)

通过扩展核心功能并在lib/extensions中添加文件,我具有相同的结构

我通过添加

解决了这个问题
# config/application.rb
#
class Application < Rails::Application
  ...
  Rails.autoloaders.main.ignore(Rails.root.join('lib/extensions'))
end

我仍然像以前一样初始化扩展名:

Dir[Rails.root.join('lib', 'extensions', '**', '*.rb')].each { |f| require f }