Rails 3库直到require才加载

Ben*_*Ben 24 require ruby-on-rails-3

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

/ lib
  opentok.rb
  / OpenTok
    Exceptions.rb
    OpenTokSDK.rb
    Session.rb

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

config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Run Code Online (Sandbox Code Playgroud)

我在/ 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 
Run Code Online (Sandbox Code Playgroud)

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

Tyl*_*ick 72

只要文件中的类是在该文件中定义的类,自动加载就可以正常工作.如果您想要重新打开现有类(最初在标准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
Run Code Online (Sandbox Code Playgroud)

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

什么会触发此文件自动加载?没有!自动加载基于常量,并不断ActiveRecord::Base已经被加载(从activerecord宝石).

因此,ActiveRecord::Base在应用程序中引用常量不会导致此特定文件自动加载.

解决方法:

这就是我要做的事情,以确保我lib/需要的所有Ruby文件:

添加config/initializers/require_files_in_lib.rb以此内容命名的新初始化程序:

Dir[Rails.root + 'lib/**/*.rb'].each do |file|
  require file
end
Run Code Online (Sandbox Code Playgroud)

  • 我同意,这通常是一个更好的主意,但它并不总是可能的,例如,如果你有一个文件重新打开*现有*类而不是定义*new*类.在这种情况下该怎么做的任何建议? (2认同)
  • 有时`config.autoload_paths`是不够的,比如config.threadsafe!已启用,要求这种方式的课程效果很好! (2认同)

Chr*_*ald 30

自动加载器会将常量变为蛇形,因此"OpenTok"会使自动加载器查找"open_tok.rb",而不是"opentok.rb".尝试重命名lib/opentok.rb,它应该可以正常工作.