I'm trying to load the Tokbox SDK in rails 3. I've placed the library in my /lib directory, so currently my directory structure looks like so:
/lib
opentok.rb
/OpenTok
Exceptions.rb
OpenTokSDK.rb
Session.rb
I'm loading all files in the /lib directory using the following in application.rb:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Other files I have in the /lib directory are auto-loading just fine, but this library does not load until I add a 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
What is the correct way to load the library in Rails 3?
Auto-loading works fine as long as the class in your file is a class that is only defined in that file. It doesn't work if you're wanting to re-open an existing class (originally defined in standard Ruby, Rails, or another library) and customize it in some way.
Example of problem:
Here's an example of a file in lib/ that would never get autoloaded:
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
This file reopens ActiveRecord::Base
and adds some methods to that class.
What would trigger this file to get autoloaded?? Nothing! Auto-loading is based on constants, and the constant ActiveRecord::Base
has already been loaded (from the activerecord
gem).
So referencing the constant ActiveRecord::Base
in your app would not cause this particular file to be auto-loaded.
Workaround:
This is what I do to ensure that all my Ruby files under lib/
get required:
Add a new initializer named config/initializers/require_files_in_lib.rb
with this contents:
Dir[Rails.root + 'lib/**/*.rb'].each do |file|
require file
end