25

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?

2 Answers 2

75

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
Sign up to request clarification or add additional context in comments.

5 Comments

Generally, you want to use config.autoload_paths in Rails, so that it can properly load/unload files.
I agree, that would generally be a better idea, but it's not always possible, for example if you have a file that reopens an existing class rather than defining a new class. Any suggestions for what to do in that case?
@m33lky I am trying to load classes in the lib folder and sub directories of the lib folder but rails does not like it. Rails doesn't like sub folders and auto loading. I do not like this work around because it bypasses the class caching but I do not have any other options. I blame rails for being rails.
thanks a lot, I also post your idea to : stackoverflow.com/a/14209677/445908
For times when config.autoload_paths isn't enough, like when config.threadsafe! is enabled, requiring classes this way works great!
30

The autoloader will snake case the constant, so "OpenTok" would make the autoloader look for "open_tok.rb", not "opentok.rb". Try renaming lib/opentok.rb and it should work fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.