Rails.application.config.autoload_paths与标准Ruby require / require_relative有什么区别?

我在application.rb中看到以下配置:

config.autoload_paths += %W(#{config.root}/app/models/custom_pack/base) config.autoload_paths += Dir["#{config.root}/app/models/custom_pack/custom_container/**/"] config.autoload_paths += Dir["#{config.root}/app/models/custom_pack/helpers/**/"] config.autoload_paths += Dir["#{config.root}/app/models/custom_pack/extensions/**/"] 

在autoload_paths中:

 Rails.application.config.autoload_paths.grep /custom/ => ["/Users/dviglione/projects/core/app/models/custom_pack/base", "/Users/dviglione/projects/core/app/models/custom_pack/custom_container/", "/Users/dviglione/projects/core/app/models/custom_pack/helpers/", "/Users/dviglione/projects/core/app/models/custom_pack/extensions/"] 

但是这些文件没有被加载。 因为我收到错误:

  `method_missing': undefined method `create_element' for # 

create_element方法是在应该加载的其中一个文件中定义的。

但是,当我使用require / require_relative时,它确实有效:

 # /initializers/my_initializer.rb require "custom_pack/base" # models/custom_pack/base.rb require_relative 'custom_container/base' require_relative 'custom_container/parent' require_relative 'custom_container/child' Dir[File.join(File.expand_path("../helpers", __FILE__), "*_helper.rb")].each { |file| require file } Dir[File.join(File.expand_path("../extensions", __FILE__), "*_adapter.rb")].each { |file| require file } 

根据我从文档中读到的内容,当您使用require’erb’时,Ruby会在$ LOAD_PATH中列出的目录中查找该文件。 也就是说,Ruby遍历其所有目录,并且每个目录检查它们是否有一个名为“erb.rb”的文件。 如果找到任何一个,解释器会加载它并结束搜索。 否则,它会再次尝试列表的下一个目录。 如果列表用尽,则引发LoadError。 对于自动加载,我们的想法是当一个像Post这样的常量被击中并丢失时,如果在app / models中有一个post.rb文件,Rails会找到它,对它进行评估,并将Post定义为副作用。 Rails有一个类似$ LOAD_PATH的目录集合,可以在其中查找post.rb. 该集合称为autoload_paths。

那么为什么require / require_relative工作,但autoload_paths不工作?

这里有许多事情可以发生。

1.如果文件跟随路径: lib/foo/bar.rb则需要定义类,如:

 class Foo::Bar end 

2.Autoload也懒惰加载文件,这意味着你的模型只在你调用时加载。 例如 :

 puts "I was loaded!" class MyLibrary end irb(main):001:0> require 'mylibrary' I was loaded! => true irb(main):001:0> autoload :MyLibrary, 'mylibrary' => nil irb(main):002:0> MyLibrary.new I was loaded! => # 

至于autoload的实际使用情况,建议开始使用require 。 理论上, autoload听起来不错,但是当某些类依赖于其他模块时,它可能会导致问题。 因为这个自动加载正在被弃用 。