Answers:
从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)
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]
来源:Rails 3快速提示:自动加载包括所有子目录的lib目录,避免延迟加载
请注意,仅在服务器启动时才加载lib文件夹中包含的文件。如果您希望自动重新加载这些文件,请阅读:Rails 3快速提示:在开发模式下自动重新加载lib文件夹。请注意,这并不适合生产环境,因为永久性重新加载会降低机器的速度。
我认为其他答案已经充分介绍了控制从中完成自动加载的文件夹的选项。但是,如果有人根据需要修改了自动加载路径后却加载了麻烦的东西,那么此答案将试图解释自动加载背后的魔力是什么。
因此,从子目录加载内容时,您应该知道一个陷阱或约定。有时,Ruby / Rails魔术(这次主要是Rails)可能使您难以理解为什么发生了某些事情。仅当模块名称与父目录名称相对应时,才会加载在自动加载路径中声明的任何模块。因此,如果您尝试输入以下内容lib/my_stuff/bar.rb
:
module Foo
class Bar
end
end
它不会自动加载。再一次,如果您将父目录重命名为,foo
从而将模块托管在路径:lib/foo/bar.rb
。它将为您服务。另一个选择是通过模块名称来命名要自动加载的文件。显然,那时只有一个名称相同的文件。万一您需要将您的内容拆分为多个文件,您当然可以使用一个文件来要求其他文件,但是我不建议这样做,因为在开发模式下修改其他文件时,Rails无法自动进行为您重新加载。但是,如果您确实希望,可以在模块名称旁边有一个文件,然后指定使用该模块所需的实际文件。因此,您可能有两个文件:lib/my_stuff/bar.rb
和lib/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”,请不要使用“ autoload”方法!
“ config.autoload_paths ”方法:仅在加载仅在一个位置定义的类时有效。如果已经在其他地方定义了某个类,则无法通过这种方法再次加载它。
“ config / initializer / load_rb_file.rb ”方法:始终有效!无论目标类是新类,还是现有类的“开放类”或“猴子补丁”,它始终有效!
有关更多详细信息,请参阅:https : //stackoverflow.com/a/6797707/445908
就我而言,我试图直接在lib目录下直接加载文件。
在application.rb中...
require '/lib/this_file.rb'
即使在控制台中也无法正常工作,然后当我尝试
require './lib/this_file.rb'
Rails会完美加载文件。
我仍然还是个菜鸟,我不确定为什么会这样,但是它能正常工作。如果有人想向我解释一下,我将不胜感激:DI希望这对任何人都可以有所帮助。
我有同样的问题。这是我解决的方法。该解决方案将加载lib目录和所有子目录(不仅是直接目录)。当然,您可以将其用于所有目录。
# application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Expected lib/bar/foo.rb to define constant Foo
如果尝试通过引用Foo加载lib / foo.rb不变。
如果只有某些文件需要访问lib中的模块,只需将require语句添加到需要它的文件即可。例如,如果一个模型需要访问一个模块,请添加:
require 'mymodule'
在model.rb文件的顶部。
require
在Rails应用程序中使用它,因为它会阻止ActiveSupport::Dependencies
适当地[卸载]该代码。相反,您应该使用config.autoload_paths
上述答案,然后根据需要添加/扩展。
require
Rails应用程序中的任何位置?在rake任务中,我当前正在require
和- include
驻留在其中的模块lib/
。我不应该那样做吗?
由于Rails 5
,建议把lib文件夹的应用程序目录下或代替创建其他有意义的名字空间的文件夹services
,presenters
,features
等等,然后将其放在app目录下,以通过rails自动加载。
请同时查看此GitHub讨论链接。
有几种原因可能会导致您从lib加载时遇到问题-有关详细信息,请参见此处-http: //www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/
app/lib
。