是什么Rails.application.config.autoload_paths和标准的Ruby

2019-10-29 07:44发布

我看到,在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 #<MyElement:0x007f82eca39898> 

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

然而,当我使用需要/ 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 }

从我从文档阅读,当您使用需要“再培训局”,红宝石查找在$ LOAD_PATH列出的目录中的文件。 也就是说,红宝石遍历所有的目录,并为他们每个人检查他们是否有一个名为“erb.rb”文件。 如果发现任何人,解释负载,并结束搜索。 否则,它在列表中的下一个目录再次尝试。 如果列表被用尽,LoadError提高。 对于自动加载,这个想法是,当一个像邮政恒定的命中和丢失,如果有在应用例如post.rb文件/模型Rails的是要找到它,评价它,并发表定义为一个副作用。 Rails有类似$ LOAD_PATH目录的集合,在其中查找post.rb. 这个集合称为autoload_paths。

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

Answer 1:

有很多事情可以在此处继续。

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!
=> #<MyLibrary:0x0b1jef>

至于实际使用情况autoload ,建议开始使用require来代替。 从理论上讲autoload听起来不错,但它可能会导致问题时,某些类依赖于其他模块。 因此自动加载处于被弃用的过程 。



文章来源: What is the difference between Rails.application.config.autoload_paths and standard Ruby require/require_relative?