我将文件名g.rb放在Rails.root/lib
侧文件夹中
文件内容如下:
module Google
end
然后我添加
config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs)
到我的Rails.root/config/application.rb
但是,当我尝试从rails console
调用Google时,会抛出异常。只有执行require 'google'
时,例外才会消失。
为什么?我的文件不应该自动加载,不应该在没有任何额外require
语句的情况下访问该模块吗?
答案 0 :(得分:113)
google.rb
内,直接放在/ lib下(如果我从/ lib指定自动加载)。
如果我想自动加载Google::Docs
,请将其放在google.rb
或google/docs.rb
中
答案 1 :(得分:27)
我有一个类似的问题让我的模块在Heroku上运行。除了Stephen C所述的自动加载命名约定之外,我发现由于Rails的生产环境在Heroku上做出require
假设,模块代码必须是threadsafe
''(即使{我在threadsafe
配置文件中注释掉了{1}}。一旦我在模块上调用production.rb
之前require
'模块文件,一切都开始工作。
include
请参阅this excellent article,了解如何在Heroku(生产)中正确加载模块。
答案 2 :(得分:24)
那是因为自动加载的重点是而不是以“预先要求”所有事情(启动惩罚)。在需要/引用时加载类。为了做到这一点,你需要一些方法来知道在哪里寻找类。否则,您必须提前加载autoload目录中的每个文件以查看声明了哪些类。这是一个权衡,但提前要求一切(如marbaq建议)不是自动加载。 您可以使用Ruby提供的autoload命令,它接受两个参数,即加载模块(符号化,即:在您的情况下为Google),第二个参数是文件名,如果lib在您的文件中,则为g.rb加载路径($ :)。请参阅Ruby文档以了解自动加载。
答案 3 :(得分:7)
将config.autoload_paths
更改为config.eager_load_paths
(基于Rails issue #6850和Force reload! from lib directory in rails 3.2 console)
答案 4 :(得分:1)
我刚才面临同样的问题,而我的“解决方案”(或者更确切地说是解决方法)是在我的application.rb中手动要求Rails.root / lib中的每个所需文件。
require 'lib/message'
require 'lib/store'
require 'lib/vault/vault.rb'
require 'lib/custom_loggers'
module MyApplication
class Application < Rails::Application
我的下一步是按照您的提及对模块文件夹中的文件进行分类。
答案 5 :(得分:-5)
我最近找到了这个解决方案
<强>配置/ application.rb中强>
module AppName
class Application < Rails::Application
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
config.autoload_paths += Dir[Rails.root.join('app', 'lib', 'extensions')]
end
end
第一个配置调用会导致rails自动加载app / models目录的所有子目录 所以现在我可以自动加载/app/models/sub_directory/model.rb (方便组织具有大量代码库的应用程序)
第二个配置调用导致rails自动加载lib / extensions目录
希望这会有所帮助
注意:我相信这是特定于rails 3的