Ruby on rails 将lib添加到';配置自动加载路径';在Rails 3中,不会自动加载我的模块

Ruby on rails 将lib添加到';配置自动加载路径';在Rails 3中,不会自动加载我的模块,ruby-on-rails,Ruby On Rails,我将文件名g.rb放在sideRails.root/lib文件夹中 文件内容如下所示: module Google end 然后我加上 config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs) 到myRails.root/config/application.rb 然而,当我试图从rails控制台调用Google时,抛出了一个异常。只有当我执行require'google'时,异常才会消失。

我将文件名g.rb放在side
Rails.root/lib
文件夹中 文件内容如下所示:

module Google
end
然后我加上

config.autoload_paths += %W(#{config.root}/lib #{Rails.root}/app/delayed_jobs)
到my
Rails.root/config/application.rb

然而,当我试图从
rails控制台
调用Google时,抛出了一个异常。只有当我执行
require'google'
时,异常才会消失。
为什么?我的文件是否应该自动加载,我是否应该在没有任何额外的
require
语句的情况下访问模块?

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

,我刚才遇到了同样的问题,我的“解决方案”(或者更确切地说是解决办法)是手动从我的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
需要“lib/message”
需要“lib/store”
需要“lib/vault/vault.rb”
需要“lib/custom_记录器”
模块MyApplication
类应用程序

我的下一步将是对您提到的模块文件夹中的文件进行分类

这是因为自动加载的目的不是预先“要求”一切(启动惩罚)。类在需要/引用时加载。为了做到这一点,你需要知道在哪里可以找到这个类。否则,您必须提前加载自动加载目录中的每个文件,以查看声明了哪些类。这是一个折衷方案,但要求所有事情都提前(正如marbaq所建议的)并不是自动加载。
您可以使用Ruby提供的autoload命令,该命令包含两个参数,即要加载的模块(在您的示例中用符号表示,即:Google),第二个参数是文件名,如果lib位于加载路径($:)中,则为g.rb。请参阅Ruby文档以获取自动加载。

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

require 'mymodule'
include Mymodule

请看一看如何在Heroku(生产)中正确加载模块。

我最近发现了这个解决方案

config/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
模块AppName
类应用程序
第一个config调用诱导rails自动加载app/models目录的所有子目录 现在我可以自动加载/app/models/sub_目录/model.rb了 (便于组织具有大型代码库的应用程序)

第二个config调用将诱导rails自动加载lib/extensions目录

希望这有帮助


注意:我相信这是rails 3特定的

更改
config.autoload\u路径
config.eager\u load\u路径


(基于和)

那么这是一个bug还是一个约定?我相信这是约定。Rails采用常量名称并使用它们生成路径:转换为/用于此目的。所以Google::Docs变成了Google/Docs.rb。你可以对这个功能的有用性进行辩论,但这是我对当前功能的理解。它本身并不是一个惯例,而是Ruby解释器寻找事物的方式,据我所知,这只是发生在我身上。我真的不关心约定,我可以重命名我的模块。我永远也猜不到这一点+1.这是Rails的惯例,而不是Ruby oneHi@morbaq,今天我遇到了同样的问题,您的解决方案非常有效,只是想说声谢谢:D+1这应该是公认的答案。链接应该对任何人都有帮助,线程安全实际上是我的问题。谢谢。顺便说一句,惯例上说你应该把lib/g.rb重命名为lib/google.rb,然后就可以上路了。