Rails 5: Завантажте файли lib у виробництво


128

Я оновив один із моїх програм із Rails 4.2.6 до Rails 5.0.0. У Посібнику з оновлення йдеться про те, що функція автозавантаження зараз відключена у виробництві за замовчуванням.

Тепер я завжди отримую помилку на своєму виробничому сервері, оскільки я завантажую всі файли lib з автоматичним завантаженням у application.rbфайл.

module MyApp
    class Application < Rails::Application
        config.autoload_paths += %W( lib/ )
    end
end

На даний момент, я встановити config.enable_dependency_loadingв , trueале мені цікаво , якщо є краще рішення цієї проблеми . Повинно бути причиною того, що автозавантаження вимкнено у виробництві за замовчуванням.


божевільна річ, і документи все ще говорять вам зробити auto_load. Я дуже розгубився, що йде не так у виробництві env для нового додатка. А оскільки я почав вчитися з Rails 5, я не читав посібник з міграції. Я подав док-питання, щоб сподіватися вирішити це: github.com/rails/rails/isissue/27268
akostadinov

1
дивно, що у мене є два файли в режимі lib, один файл легко доступний в Runtime, але інший потрібно вимагати вручну: D
ілюзіоніст

@Tobias Яке рішення ти закінчив?
геобой

@geoboy Код групи (як Validators) у папках безпосередньо в додатку / каталозі, оскільки код завантажується автоматично.
Тобіас

мова йде про правильному шляху до файлу і визначення класу тут , що робота для мене в Rails 5.2: Шлях до файлу: app/services/paylinx/paylinx_service.rbВизначення класу: module Paylinx class PaylinxService end end. Я спробував ці autoload_pathsречі. не працює для мене.
NamNamNam

Відповіді:


161

Мій список змін після переходу на Rails 5:

  1. Місце libреж в appтому , що весь код всередині програми буде автоматично завантажуються в розробника і нетерплячий завантажені в прод і найголовніше це autoreloaded в розвитку , так що вам не потрібно перезавантажувати сервер кожен раз , коли ви робите зміни.
  2. Видаліть будь-які requireзаяви, що вказують на ваші власні класи всередині, libоскільки всі вони все одно автоматично завантажуються, якщо їх ім'я файлів / dir є правильним, і якщо ви залишите requireоператори, це може порушити автоматичну завантаження. Більше інформації тут
  3. Встановіть config.eager_load = trueу будь-яких середовищах, щоб побачити проблеми завантаження коду з нетерпінням.
  4. Використовуйте Rails.application.eager_load!перед грою з нитками, щоб уникнути помилок "кругової залежності".
  5. Якщо у вас є розширення в рубінах / рейках, залиште цей код у старому 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 }

8
То як libтепер використовується папка? Я маю на увазі переміщення libрежисера в appдір, схоже, начебто вирішення проблеми.
Мартін Свобода

3
/app/lib/розмістили файл / клас, і це НЕ автоматично завантажується. випробуваний в рейках 5.1, новий проект
Тім Кречмер

29
Варто зазначити, що вам потрібно зупинити весну. Я перемістив усе до app / lib /, а потім витратив трохи часу, цікавлячись, чому я все ще не можу використовувати свої класи з консолі. весна зупинка ftw :)
jacklin

1
Куди піде наступний рядокRails.application.eager_load!
Стівен Агілар

1
Це може працювати, але це не найкраще рішення. Семантична структура папок також є семантичною. Речі libмають іншу близькість до проекту, ніж речі в appкаталозі. Декілька інших відповідей кращі, ніж ця.
CWitty

84

Я просто використав config.eager_load_pathsзамість того, config.autoload_pathsщоб згадати, якщо акостадінов про коментар github: https://github.com/rails/rails/isissue/13142#issuecomment-275492070

# config.autoload_paths << Rails.root.join('lib')
config.eager_load_paths << Rails.root.join('lib')

Він працює над розвитком та виробничим середовищем.

Спасибі Johan за пропозицію замінити #{Rails.root}/libз Rails.root.join('lib')!


3
Працює як шарм. Мені не сподобався синтаксис, тому він змінив його config.eager_load_paths << Rails.root.join('lib').
3limin4t0r

2
Для мене це була найкраща відповідь. Мій проект розпочався на Rails 5.2 з нуля, і папка / lib все ще створювалася поза папкою / app. Я не бачив вагомої причини перенести це.
Самір Хаддад

1
Так, це працює! Здається, Rails Devs дуже сподобається, викликаючи проблеми з завантаженням lib: D до наступного разу!
Дамієн Рош

Для Rails 5.2 використовує config.eager_load_paths += [Rails.root.join('lib')]замість цього config.eager_load_pathsзаморожений масив
William Wong Garay

@WilliamWongGaray config.eager_load_paths доступний лише для читання, коли ви намагаєтесь змінити його в ініціалізаторі. Коли ви додасте шляхи до application.rbнього, він буде працювати з використанням обох методів.
Michał Zalewski

31

Автозавантаження вимикається у виробничих умовах через безпеку ниток. Дякую @ Зелёный за посилання.

Я вирішив цю проблему, зберігаючи файли lib у libпапці в моєму appкаталозі, як рекомендовано на Github . Кожна папка в appпапці автоматично завантажується Rails.


6
Якщо ви не хочете копати довгу дискусійну нитку на Github, ви можете знайти пояснення дистильованої тут: kolektividea.com/blog/archives/2016/07/22/…
Ернест

7
Я використав config.eager_load_paths << "#{Rails.root}/lib", що краще IMO дотримуватися рекомендованої структури додатків для рейкових плат.
акостадінов

2
Поставив lib app/lib Рекомендується рейками члени github.com/rails/rails/issues/13142#issuecomment-275549669
EXA

4
Це повністю руйнує те, що є метою lib. Я б зачекав, коли тендер чи DHH задзвонить. Тим часом я (особисто) рекомендую дотримуватися відповіді @Lev Lukomsky.
Джош Броді

@JoshBrody Зараз я вважаю, що /libкаталог вам взагалі не потрібен . Сторонні губки - це найчастіше дорогоцінні камені, і якщо ні, то їх слід створити. Для інших файлів я створюю конкретні папки в /appкаталозі. Наприклад validators.
Тобіас

22

Повинно бути причиною того, що автозавантаження вимкнено у виробництві за замовчуванням.

Ось довге обговорення цього питання. https://github.com/rails/rails/isissue/13142


1
Ця дискусія є найкращим, хоч і тривалим, прочитаним, джерелом інформації по цій темі, яку я натрапив.
Джейсон

12

Це дозволяє мати автоматичне завантаження lib і працює і у виробничому середовищі.

PS Я змінив свою відповідь, тепер вона додає обидва нетерплячі шляхи автозавантаження, незалежно від оточення, щоб дозволити працювати і в користувацьких середовищах (наприклад, на етапі)

# config/initializers/load_lib.rb
...
config.eager_load_paths << Rails.root.join('lib')
config.autoload_paths << Rails.root.join('lib')
...

2
Чи можете ви розширити, чому це вирішує проблему?
Stuart.Sklinar

@ Stuart.Sklinar це дозволяє мати автоматичне завантаження lib, і працює і у виробничому середовищі. PS Я змінив свою відповідь, тепер вона додає обом охочим - автозавантаження шляхів, незалежно від навколишнього середовища, щоб дозволити роботу і в користувацьких середовищах (наприклад, на етапі)
srghma

1
Чи можете ви розширитись (у своїй відповіді)? Відповідь лише на код не дуже допомагає нікому зрозуміти, чому це слід робити "таким чином" - я повинен додати, що я не Ruby Dev, просто допомагаю зрозуміти SO. Додавання коментаря до "лише відповіді на код" дасть йому деякий фактичний контекст.
Стюарт.Склінар

1
@ Stuart.Sklinar sure
srghma

6

Просто змініть config.autoload_paths на config.eager_load_paths у файлі config / application.rb. Тому що в рейках 5 автозавантаження вимкнено для виробничого середовища за замовчуванням. Більш детальну інформацію можна отримати за посиланням .

 #config.autoload_paths << "#{Rails.root}/lib"
  config.eager_load_paths << Rails.root.join('lib')

Це працює як для розвитку навколишнього середовища, так і для виробництва.


4

У певному сенсі тут є уніфікований підхід у Rails 5 для централізації налаштованих налаштувань на автоматичне завантаження та одночасне додавання необхідного шляху автозавантаження, коли налаштоване прагнення до завантаження, інакше воно не зможе працювати належним чином:

# config/application.rb
...
config.paths.add Rails.root.join('lib').to_s, eager_load: true

# as an example of autoload only config
config.paths.add Rails.root.join('domainpack').to_s, autoload: true
...

2

Для тих, хто боровся з цим, як я, недостатньо просто помістити каталог під app/. Так, ви отримаєте автоматичне завантаження, але не потрібне перезавантаження, що вимагає виконання умов про розширення імен .

Також використання ініціалізатора для завантаження старого кореневого рівня libзапобіжить функцію перезавантаження під час розробки.


0

Переміщення папки Lib у програму допомогло вирішити проблему, мої api у Twitter не працюватимуть у виробництві. У мене був "неініціалізований постійний TwitterApi", і мій API Twitter був у моїй папці lib. Я мав config.autoload_paths += Dir["#{Rails.root}/app/lib"]у своєму application.rb, але він не працював перед переміщенням папки.

Це зробило трюк


-6

підсумувати відповідь Лева: mv lib appвистачило, щоб мати все своєlib код був автоматично завантажений / автоматично перезавантажений.

(рейки 6.0.0beta3, але також повинні працювати добре на рейках 5.x)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.