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

从github:

在这次提交中做了一些更改: 不自动加载代码在*lib*的应用程序(现在你需要显式 要求他们)。这使得应用程序的行为更接近于引擎 (lib中的代码仍然是自动加载插件);


当前回答

自动装填东西的魔力

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

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

module Foo
  class Bar
  end
end

It will not be loaded automagically. Then again if you rename the parent dir to foo thus hosting your module at path: lib/foo/bar.rb. It will be there for you. Another option is to name the file you want autoloaded by the module name. Obviously there can only be one file by that name then. In case you need to split your stuff into many files you could of course use that one file to require other files, but I don't recommend that, because then when on development mode and you modify those other files then Rails is unable to automagically reload them for you. But if you really want you could have one file by the module name that then specifies the actual files required to use the module. So you could have two files: lib/my_stuff/bar.rb and lib/my_stuff/foo.rb and the former being the same as above and the latter containing a single line: require "bar" and that would work just the same.

P.S. I feel compelled to add one more important thing. As of lately, whenever I want to have something in the lib directory that needs to get autoloaded, I tend to start thinking that if this is something that I'm actually developing specifically for this project (which it usually is, it might some day turn into a "static" snippet of code used in many projects or a git submodule, etc.. in which case it definitely should be in the lib folder) then perhaps its place is not in the lib folder at all. Perhaps it should be in a subfolder under the app folder· I have a feeling that this is the new rails way of doing things. Obviously, the same magic is in work wherever in you autoload paths you put your stuff in so it's good to these things. Anyway, this is just my thoughts on the subject. You are free to disagree. :)


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

As severin pointed out in his comment, the core "autoload a module mechanism" sure is part of Ruby, but the autoload paths stuff isn't. You don't need Rails to do autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar"). And when you would try to reference the module Foo for the first time then it would be loaded for you. However what Rails does is it gives us a way to try and load stuff automagically from registered folders and this has been implemented in such a way that it needs to assume something about the naming conventions. If it had not been implemented like that, then every time you reference something that's not currently loaded it would have to go through all of the files in all of the autoload folders and check if any of them contains what you were trying to reference. This in turn would defeat the idea of autoloading and autoreloading. However, with these conventions in place it can deduct from the module/class your trying to load where that might be defined and just load that.

其他回答

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

Ruby on rails 3不会自动重载/lib文件夹中的代码。我把它放到ApplicationController里面

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

正确地拼写文件名。

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

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

从Rails 5开始,建议将lib文件夹放在app目录下,或者为文件夹创建其他有意义的名称空间,如服务、演示器、功能等,并将其放在app目录下,以便由Rails自动加载。

请检查这个GitHub讨论链接。

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

config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]

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

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