Я использую следующую строку в инициализаторе для автозагрузки кода в моем /lib
каталоге во время разработки:
конфиг / Инициализаторы / custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(из Rails 3 Quicktip: автоматическая перезагрузка папок lib в режиме разработки )
Он отлично работает, но слишком неэффективен для использования в производстве. Вместо того, чтобы загружать библиотеки при каждом запросе, я просто хочу загрузить их при запуске. В этом же блоге есть еще одна статья, описывающая, как это сделать:
конфиг / application.rb:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
Однако, когда я переключаюсь на это, даже в процессе разработки, я получаю NoMethodErrors при попытке использовать функции lib.
Пример одного из моих файлов lib:
Библиотека / extensions.rb:
Time.class_eval do
def self.milli_stamp
Time.now.strftime('%Y%m%d%H%M%S%L').to_i
end
end
При Time.milli_stamp
вызове выбрасывается NoMethodError
Я понимаю, что другие отвечали на аналогичные вопросы по SO, но все они, похоже, имеют дело с соглашениями об именах и другими проблемами, о которых мне раньше не приходилось беспокоиться - мои классы lib уже работали для загрузки по запросу, я просто хочу изменить это для загрузки при запуске . Какой правильный способ сделать это?
Ответы:
Я думаю, что это может решить вашу проблему:
в config / application.rb :
и придерживайтесь правильного соглашения об именах в lib .
в lib / foo.rb :
в lib / foo / bar.rb :
если вы действительно хотите сделать какие-то обезьяньи патчи в файле, например lib / extensions.rb , вам может потребоваться это вручную:
в config / initializer / require.rb :
PS
Rails 3 модули / классы автозагрузки Билла Хардинга.
И чтобы понять, что именно Rails делает с автоматической загрузкой?
читайте автозагрузку Rails - как это работает, а когда нет - Саймон Коффи.
источник
config.eager_load_paths << Rails.root.join('lib')
. Однако, это имеет большой недостаток в том, чтоeager_load_paths
загружает все и в задачи. Я думаю, что решение Лулалала лучше. Вот сообщение в блоге с более подробной информацией: blog.arkency.com/2014/11/…Хотя это не дает прямого ответа на вопрос, но я думаю, что это хорошая альтернатива, чтобы вообще избежать вопроса.
Чтобы избежать всех хлопот
autoload_paths
илиeager_load_paths
проблем, создайте каталог «lib» или «misc» в каталоге «app». Размещайте коды, как обычно, и Rails будет загружать файлы так же, как он будет загружать (и перезагружать) файлы модели.источник
app
, мне нужно сделать это вручную ...... или нужно поместить его в путь автозагрузки ..app/views
каталог, который не добавляется; или, скорее, явно удаляется.lib
он предназначен для кода, который может быть применен к нескольким проектам и может быть извлечен в гем. Если нет, создайте более подходящую папку под приложением, ищите какservices/
илиpresenters/
даже подкаталоги из них.Это может помочь кому-то вроде меня, который найдет этот ответ при поиске решений о том, как Rails обрабатывает загрузку классов ... Я обнаружил, что мне нужно было определить,
module
чье имя соответствовало моему имени файла, а не просто определить класс:В файле lib / development_mail_interceptor.rb (да, я использую код из Railscast :))
работает, но не загружается, если бы я не поместил класс в модуль.
источник
LOAD_PATH/module/class.rb
(подчеркнутом) местеLOAD_PATH
в путях загрузки, используемых приложением Ruby (autoload_paths в случае Rails).lib
колебался от автоматической загрузки Rails до отсутствия автоматической загрузки, а в последних версиях (> = Rails 3.x) он не загружался автоматически. Какая бы магия ни делала для вас эту работу, не рекомендуется. Возможно, это старый Railscast?Используйте config.to_prepare для загрузки патчей / расширений обезьян для каждого запроса в режиме разработки.
конец
источник