Rails 5: загрузка файлов lib в производство
Я обновил одно из своих приложений от Rails 4.2.6 до Rails 5.0.0. В Руководство по обновлению говорится, что функция Autoload отключена по умолчанию.
Теперь я всегда получаю сообщение об ошибке на моем рабочем сервере, так как я загружаю все файлы lib с автозагрузкой в файл application.rb
.
module MyApp
class Application < Rails::Application
config.autoload_paths += %W( lib/ )
end
end
В настоящее время я установил config.enable_dependency_loading
в true
, но мне интересно, есть ли лучшее решение для этого. Должна быть причина, по которой Autoloading отключается в производстве по умолчанию.
Ответы
Ответ 1
Автозагрузка отключена в рабочей среде из-за безопасности потоков. Спасибо @Зелёный за ссылку.
Я решил эту проблему, сохранив файлы lib в папке lib
в моем каталоге app
, как рекомендовано в Github. Каждая папка в папке app
автоматически загружается Rails.
Ответ 2
Мой список изменений после перехода на Rails 5:
- Поместите
lib
dir в app
, потому что весь код внутри приложения автоматически загружается в dev и загружается в prod и, самое главное, автоматически загружается в процессе разработки, поэтому вам не нужно перезапускать сервер каждый раз, когда вы вносите изменения.
- Удалите все инструкции
require
, указывающие на ваши собственные классы внутри lib
, потому что все они автоматически загружаются, если имена файлов /dir верны, и если вы оставите require
заявления, это может сломать автозагрузку. Подробнее здесь
- Установите
config.eager_load = true
во всех средах, чтобы увидеть проблемы с загрузкой кода с нетерпением в dev.
- Используйте
Rails.application.eager_load!
перед воспроизведением с потоками, чтобы избежать ошибок "круговой зависимости".
-
Если у вас есть расширения ruby /rails, оставьте этот код в старой директории lib
и загрузите их вручную из инициализатора. Это обеспечит загрузку расширений до вашей следующей логики, которая может зависеть от нее:
# config/initializers/extensions.rb
Dir["#{Rails.root}/lib/ruby_ext/*.rb"].each { |file| require file }
Dir["#{Rails.root}/lib/rails_ext/*.rb"].each { |file| require file }
Ответ 3
Должна быть причина, по которой автозагрузка отключена в по умолчанию.
Вот длинная дискуссия по этой проблеме. https://github.com/rails/rails/issues/13142
Ответ 4
Я просто использовал config.eager_load_paths
вместо config.autoload_paths
, как упоминал akostadinov о комментарии github:
https://github.com/rails/rails/issues/13142#issuecomment-275492070
# config.autoload_paths << "#{Rails.root}/lib"
config.eager_load_paths << "#{Rails.root}/lib"
Он работает в среде разработки и производства.
Ответ 5
Для тех, кто боролся с этим, как и я, недостаточно просто разместить каталог под app/
. Да, вы получите автозагрузку, но не обязательно перезагрузка, которая требует выполнения соглашений об именах.
Кроме того, использование инициализатора для загрузки старого корневого уровня lib
предотвратит функцию перезагрузки во время разработки.
Ответ 6
Перемещение папки lib в приложение помогло решить проблему, мой Twitter-ави не запускался на производстве. У меня был "неинициализированный постоянный TwitterApi", и мой Twitter API был в моей папке lib.
У меня был config.autoload_paths += Dir["#{Rails.root}/app/lib"]
в моем приложении .rb, но он не работал, прежде чем перемещать папку.
Это сделало трюк