Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 library not loading until require

Tags:

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?

like image 566
Ben Avatar asked Nov 21 '10 00:11

Ben


1 Answers

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 
like image 151
Tyler Rick Avatar answered Sep 23 '22 19:09

Tyler Rick