Автоматическая загрузка lib-файлов в Rails 4
я использую следующую строку в инициализаторе для автоматической загрузки кода в my /lib
каталог во время разработки:
файл config/инициализаторы/таможня.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
(от Rails 3 Quicktip: автоматическая перезагрузка папок lib в режиме разработки)
он отлично работает, но он слишком неэффективен для использования в производстве - вместо загрузки библиотек по каждому запросу я просто хочу загрузить их при запуске. Тот же блог другой статья описание того, как это сделать:
конфиг/приложения.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:
lib / расширения.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 уже работала для загрузки по запросу я просто хочу изменить его на per -запуск загрузка. Как правильно это сделать?
4 ответов
Я думаю, это может решить вашу проблему:
-
на конфиг/приложения.rb:
config.autoload_paths << Rails.root.join('lib')
и сохранить правильное соглашение об именах в lib.
на lib / foo.rb:
class Foo end
на lib/foo / bar.rb:
class Foo::Bar end
-
если вы действительно хотите сделать некоторые патчи в файл, как lib / extensions.rb, вы можете вручную требуют это:
на config / инициализаторы / require.rb:
require "#{Rails.root}/lib/extensions"
П. С.
Rails 3 Autoload Модули / Классы Билл Хардинг.
и понять, что именно Rails делает с автоматической загрузкой?
читать автоматическая загрузка рельсов-как это работает, и когда это не Саймон Коффи.
хотя это не прямо ответить на вопрос, но я думаю, что это хорошая альтернатива, чтобы избежать вопроса вообще.
чтобы избежать всех autoload_paths
или eager_load_paths
hassle, создайте каталог" lib "или" misc "в каталоге" app". Поместите коды, как вы обычно делаете там, и Rails загрузит файлы так же, как он загрузит (и перезагрузит) файлы модели.
Это может помочь кому-то вроде меня, который находит этот ответ при поиске решений того, как Rails обрабатывает загрузку класса ... Я обнаружил, что мне нужно определить module
чье имя соответствует моему имени файла соответствующим образом, а не просто определяет класс:
в файле lib / development_mail_interceptor.rb (Да, я использую код из Railscast :))
module DevelopmentMailInterceptor
class DevelopmentMailInterceptor
def self.delivering_email(message)
message.subject = "intercepted for: #{message.to} #{message.subject}"
message.to = "myemail@mydomain.org"
end
end
end
работает, но он не загружается, если я не поместил класс внутри модуля.
использовать config.to_prepare для загрузки патчей/расширений обезьян для каждого запроса в режиме разработки.
config.to_prepare do |action_dispatcher|
# More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
Rails.logger.info "\n--- Loading extensions for #{self.class} "
Dir.glob("#{Rails.root}/lib/extensions/**/*.rb").sort.each do |entry|
Rails.logger.info "Loading extension(s): #{entry}"
require_dependency "#{entry}"
end
Rails.logger.info "--- Loaded extensions for #{self.class}\n"
конец