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 直到页面重新加载后才工作