Rails 3库直到需要才加载

Posted

技术标签:

【中文标题】Rails 3库直到需要才加载【英文标题】:Rails 3 library not loading until require 【发布时间】:2011-05-13 06:08:16 【问题描述】:

我正在尝试在 rails 3 中加载 Tokbox SDK。我已将库放在我的 /lib 目录中,所以目前我的目录结构如下所示:

/lib opentok.rb /OpenTok 异常.rb OpenTokSDK.rb 会话.rb

我正在使用 application.rb 中的以下内容加载 /lib 目录中的所有文件:

config.autoload_paths += %W(#config.root/lib)
config.autoload_paths += Dir["#config.root/lib/**/"]

我在 /lib 目录中的其他文件可以自动加载,但这个库在我添加 require 'OpenTok' 之前不会加载:

ruby-1.9.2-p0 > OpenTok
NameError: uninitialized constant OpenTok
ruby-1.9.2-p0 > OpenTok::OpenTokSDK
NameError: uninitialized constant OpenTok
ruby-1.9.2-p0 > require 'OpenTok'
 => ["OpenTok"]
ruby-1.9.2-p0 > OpenTok
 => OpenTok
ruby-1.9.2-p0 > OpenTok::OpenTokSDK
 => OpenTok::OpenTokSDK 

在 Rails 3 中加载库的正确方法是什么?

【问题讨论】:

【参考方案1】:

只要文件中的类是在该文件中定义的类,自动加载就可以正常工作。如果您想重新打开现有类(最初在标准 Ruby、Rails 或其他库中定义)并以某种方式对其进行自定义,则它不起作用。

问题示例:

这是 lib/ 中永远不会自动加载的文件的示例:

lib/active_record/base_extensions.rb:

ActiveRecord::Base   # make sure ActiveRecord::Base is loaded
module ActiveRecord::Base::Extensions
  # some methods here
end

class ActiveRecord::Base
  include ActiveRecord::Base::Extensions
end

此文件重新打开 ActiveRecord::Base 并向该类添加一些方法。

什么会触发此文件自动加载?没有!自动加载基于常量,并且常量ActiveRecord::Base已经被加载(来自activerecord gem)。

因此,在您的应用中引用常量 ActiveRecord::Base不会导致此特定文件被自动加载。

解决方法:

我这样做是为了确保lib/ 下的所有 Ruby 文件都需要:

使用以下内容添加一个名为 config/initializers/require_files_in_lib.rb 的新初始化程序:

Dir[Rails.root + 'lib/**/*.rb'].each do |file|
  require file
end

【讨论】:

一般情况下,你想在Rails中使用config.autoload_paths,这样它就可以正常加载/卸载文件了。 我同意,这通常是一个更好的主意,但并不总是可能的,例如,如果您有一个文件重新打开 现有 类而不是定义一个 类。在这种情况下该怎么做有什么建议吗? @m33lky 我正在尝试在 lib 文件夹和 lib 文件夹的子目录中加载类,但 rails 不喜欢它。 Rails 不喜欢子文件夹和自动加载。我不喜欢这种解决方法,因为它绕过了类缓存,但我没有任何其他选择。我责怪rails是rails。 非常感谢,我也将您的想法发布到:***.com/a/14209677/445908 config.autoload_paths 不够用的时候,比如config.threadsafe!已启用,以这种方式要求类效果很好!【参考方案2】:

自动加载器将蛇形大小写常量,因此“OpenTok”将使自动加载器查找“open_tok.rb”,而不是“opentok.rb”。尝试重命名 lib/opentok.rb 应该可以正常工作。

【讨论】:

以上是关于Rails 3库直到需要才加载的主要内容,如果未能解决你的问题,请参考以下文章

Javascript/JQuery 直到页面重新加载后才工作

Rails javascript仅在重新加载后才有效

使用 UIImageView+AFNetworking,图像直到滚动才会出现

delphi如何调用DLL

Delphi简单调用DLL

Ruby on Rails 3 - 为每个请求重新加载 lib 目录