最好的方法加载模块/类从lib文件夹在Rails 3?

由于最新的Rails 3版本不再从lib中自动加载模块和类, 最好的装货方式是什么?< / p >

从github:

A few changes were done in this commit:


Do not autoload code in *lib* for applications (now you need to explicitly
require them). This makes an application behave closer to an engine
(code in lib is still autoloaded for plugins);
140123 次浏览

从Rails 2.3.9开始,在config/application.rb中有一个设置,你可以在其中指定包含你想要自动加载的文件的目录。

从application.rb:

# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)

如果只有某些文件需要访问lib中的模块,只需向需要它的文件添加require语句。例如,如果一个模型需要访问一个模块,则添加:

require 'mymodule'

在模型的顶部。rb文件。

我也有同样的问题。下面是我的解决方法。解决方案加载lib目录和所有子目录(不仅仅是direct目录)。当然,您可以将此用于所有目录。

# application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]

来源:Rails 3快速提示:自动加载lib目录包括所有子目录,避免延迟加载

请注意,lib文件夹中包含的文件仅在服务器启动时加载。如果你想轻松地自动重载这些文件,请读取:Rails 3快速提示:在开发模式下自动重载库文件夹。请注意,这并不适用于生产环境,因为永久重新加载会降低机器的速度。

非常相似,但我认为这个更优雅一点:

config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]

配置。autooad_paths不适合我。我用另一种方法来解

Ruby on rails 3不会自动重载/lib文件夹中的代码。我通过放入ApplicationController来解决它

Dir["lib/**/*.rb"].each do |path|
require_dependency path
end

自动装填东西的魔力

我认为在其他答案中已经充分涵盖了控制自动加载内容的文件夹的选项。然而,如果有人有麻烦的东西加载,尽管他们已经有他们的自动加载路径修改为所需,然后这个答案试图解释什么是这个自动加载的东西背后的魔法。

所以当从子目录加载东西时,有一个你应该知道的陷阱或约定。有时候Ruby/Rails的魔力(这次主要是Rails)会让人很难理解为什么会发生某些事情。在自动加载路径中声明的任何模块只有在模块名称与父目录名称对应时才会被加载。因此,如果你试图在lib/my_stuff/bar.rb中放入如下内容:

module Foo
class Bar
end
end

它不会被自动加载。如果你将父目录重命名为foo,那么你的模块就存放在路径:lib/foo/bar.rb。它会在那里等着你。另一种选择是将您想要自动加载的文件命名为模块名。显然,只有一个文件可以使用这个名称。如果你需要将你的东西分割成许多文件,你当然可以使用一个文件来要求其他文件,但我不建议这样做,因为当你在开发模式下修改那些其他文件时,Rails无法自动地为你重新加载它们。但是如果你真的想要,你可以用一个模块名文件,然后指定使用模块所需的实际文件。所以你可以有两个文件:lib/my_stuff/bar.rblib/my_stuff/foo.rb,前者与上面相同,后者包含一行:require "bar",这将是一样的。

附注:我觉得有必要再补充一件重要的事情。最近,每当我想在lib目录中有一些需要自动加载的东西时,我倾向于开始思考,如果这是我实际上专门为这个项目开发的东西(通常是这样,它可能有一天会变成许多项目中使用的“静态”代码片段或git子模块等。在这种情况下,它肯定应该在lib文件夹中),那么它的位置可能根本不在lib文件夹中。也许它应该在app文件夹下的子文件夹中·我有一种感觉,这是新的rails做事的方式。显然,在自动加载路径中你把东西放进去的地方也有同样的魔力,这对这些东西很好。不管怎样,这只是我对这个问题的看法。你可以不同意。:)


更新:关于魔法的类型..

正如severin在他的评论中指出的,核心的“自动加载模块机制”确实是Ruby的一部分,但自动加载路径不是。你不需要Rails来做autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")。当你第一次尝试引用模块Foo时它就会为你加载。然而,Rails所做的是,它为我们提供了一种从注册文件夹中自动加载东西的方法,这已经实现了一种方式,它需要假设一些关于命名约定的东西。如果它没有这样实现,那么每次你引用一些当前没有加载的东西时,它就必须遍历所有自动加载文件夹中的所有文件,并检查它们是否包含你试图引用的内容。这反过来又会破坏自动加载和自动重新加载的想法。然而,有了这些约定,它可以从您试图加载的模块/类中扣除可能定义的地方,并只加载它。

警告:如果你想从你的lib文件夹中加载“monkey patch”或“open class”,不要使用自动装载的方法!!

  • "config.autoload_paths"方法:仅适用于加载只在一个地方定义的类。如果某个类已经在其他地方定义了,那么您就不能通过这种方法再次加载它。

  • config/initializer/load_rb_file.rb"方法:总是有效!无论目标类是一个新类,还是一个“开放类”或现有类的“猴子补丁”,它总是有效的!

更多细节,参见:https://stackoverflow.com/a/6797707/445908

有几个原因可能会导致你从库中加载时遇到问题-详情请参阅这里- http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/

  • 修复自动加载路径
  • 线程安全的相关
  • 相关的命名
  • ...

在我的情况下,我只是试图直接在lib目录下加载一个文件。

在application.rb……

require '/lib/this_file.rb'

即使是在主机上,当我尝试时,它也不起作用

require './lib/this_file.rb'

rails可以完美地加载文件。

我还是个新手,我不知道为什么这样做,但它确实有效。如果有人愿意给我解释一下,我会很感激:D我希望这能帮助到别人。

正确地拼写文件名。

认真对待。我和一个类斗争了一个小时,因为这个类是Governance::ArchitectureBoard,文件在lib/ Governance /architecture_baord中。rb (board中O和A的转置)

回想起来似乎很明显,但那是魔鬼在追踪。如果这个类没有定义在Rails基于修改类名而期望它所在的文件中,那么它就不会找到它。

Rails 5开始,建议将lib文件夹放在app目录下,或者为文件夹创建其他有意义的名称空间,如servicespresentersfeatures等,并将其放在app目录下,以便通过rails自动加载。

请检查这个GitHub讨论链接以及。