La libreria di Rails 3 non viene caricata fino a quando non viene richiesta

Sto provando a caricare il Tokbox SDK in rails 3. Ho messo la libreria nella mia directory / lib, quindi attualmente la mia struttura di directory ha il seguente aspetto:

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

Sto caricando tutti i file nella directory / lib usando quanto segue in application.rb:

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

Altri file che ho nella directory / lib si caricano automaticamente bene, ma questa libreria non viene caricata finché non aggiungo un 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 

Qual è il modo corretto di caricare la libreria in Rails 3?

Il caricatore automatico colpirà la costante, quindi “OpenTok” farà in modo che il caricatore cerchi “open_tok.rb”, non “opentok.rb”. Prova a rinominare lib / opentok.rb e dovrebbe funzionare correttamente.

Il caricamento automatico funziona bene finché la class nel file è una class definita solo in quel file. Non funziona se vuoi riaprire una class esistente (originariamente definita in Ruby standard, Rails o un’altra libreria) e personalizzarla in qualche modo.

Esempio di problema:

Ecco un esempio di un file in lib / che non verrebbe mai caricato automaticamente:

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 

Questo file riapre ActiveRecord::Base e aggiunge alcuni metodi a quella class.

Cosa potrebbe innescare questo file per ottenere autoloaded ?? Niente! Il caricamento automatico si basa sulle costanti e il costante ActiveRecord::Base è già stato caricato (dalla gem activerecord ).

Quindi fare riferimento alla costante ActiveRecord::Base nella tua app non causerebbe il caricamento automatico di questo particolare file.

Soluzione:

Questo è quello che faccio per assicurarmi che tutti i miei file Ruby sotto lib/ vengano richiesti:

Aggiungi un nuovo inizializzatore chiamato config/initializers/require_files_in_lib.rb con questo contenuto:

 Dir[Rails.root + 'lib/**/*.rb'].each do |file| require file end