Библиотека Rails 3 не загружается, пока не потребуется

Я пытаюсь загрузить Tokbox SDK в rails 3. Я поместил библиотеку в каталог my/lib, поэтому в настоящее время моя структура каталогов выглядит так:

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

Я загружаю все файлы в каталог /lib, используя следующее в application.rb:

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

Другие файлы, которые у меня есть в каталоге /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 

Каков правильный способ загрузки библиотеки в Rails 3?

Ответ 1

Автозагрузчик будет змеивать регистр константой, поэтому "OpenTok" заставит автозагрузчик искать "open_tok.rb", а не "opentok.rb". Попробуйте переименовать lib/opentok.rb, и он должен работать нормально.

Ответ 2

Автозагрузка работает отлично, пока класс в вашем файле является классом, который определен только в этом файле. Он не работает, если вы хотите повторно открыть существующий класс (первоначально определенный в стандартном 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

Этот файл снова открывает ActiveRecord::Base и добавляет некоторые методы в этот класс.

Что может заставить этот файл получить автозагрузку? Ничего! Автозагрузка основана на константах, а константа ActiveRecord::Base уже загружена (из драгоценного камня activerecord).

Таким образом, ссылка на константу ActiveRecord::Base в вашем приложении не приведет к автоматическому загрузке этого конкретного файла.

Обход проблемы:

Это то, что я делаю, чтобы получить все мои файлы Ruby под lib/:

Добавьте новый инициализатор с именем config/initializers/require_files_in_lib.rb с этим содержимым:

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