在Rails 3中将lib添加到'config.autoload_paths'不会自动加载我的模块

Phư*_*yễn 73 ruby-on-rails

我在侧Rails.root/lib文件夹中放置文件名g.rb 文件内容如下:

module Google
end
Run Code Online (Sandbox Code Playgroud)

然后我补充说

config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs)
Run Code Online (Sandbox Code Playgroud)

对我的 Rails.root/config/application.rb

但是,当我尝试从中调用Google时rails console,会抛出异常.只有在我执行时,例外才会消失require 'google'.为什么?我的文件不应该自动加载,不应该在没有任何额外require声明的情况下访问模块吗?

Phư*_*yễn 113

嗯,我发现了一件有趣的事情.为了让Rails自动加载我的类,类名应该符合文件名和文件夹结构.例如,如果我想让Google模块自动加载,我必须将它放在google.rb/ lib下直接放入(如果我从/ lib指定自动加载).如果我想自动加载Google::Docs,那么我要么把它放在里面,google.rb要么google/docs.rb

  • 我相信这是惯例.Rails采用常量名称并从中创建路径.::为此目的变成了/.所以Google :: Docs变成了google/docs.rb.你可以辩论这个的用处,但这是我对当前功能的理解. (8认同)
  • 这是一个错误或约定吗? (6认同)
  • 据我所知,它本身并不是一种约定,它是Ruby解释器查找内容的方式 (3认同)
  • 这是一个Rails约定,而不是Ruby约定 (3认同)
  • 任何人都有关于此的ruby文档的链接? (2认同)

Don*_*ham 27

让我的模块在Heroku上运行时遇到了类似的问题.除了Stephen C所说的自动加载命名约定之外,我发现模块代码必须是require由于threadsafeRails的生产环境在Heroku上做出的假设(即使threadsafe在我的production.rb配置文件中被注释掉了).因为require在调用模块之前我是模块文件include,一切都开始工作了.

require 'mymodule'
include Mymodule
Run Code Online (Sandbox Code Playgroud)

请看一下这篇关于让模块在Heroku(生产)中正确加载的优秀文章.


Ste*_*n C 24

那是因为自动加载的重点不是 "要求"所有事情(启动惩罚).在需要/引用时加载类.为了做到这一点,你需要一些方法来知道在哪里寻找类.否则,您必须提前加载autoload目录中的每个文件以查看声明了哪些类.这是一个权衡,但提前要求一切(如marbaq建议)不是自动加载.您可以使用Ruby提供的autoload命令,它接受两个参数,即加载模块(符号化,即:在您的情况下为Google),第二个参数是文件名,如果lib在您的文件中,则为g.rb加载路径($ :).请参阅Ruby文档以获取自动加载.


E. *_*mbo 7

更改config.autoload_pathsconfig.eager_load_paths

(基于Rails问题#6850强制重载!来自rails 3.2控制台中的lib目录)