Rails 5: carica i file lib in produzione

Ho aggiornato una delle mie app da Rails 4.2.6 a Rails 5.0.0. La Guida all’aggiornamento dice che la funzione di caricamento automatico ora è disabilitata in produzione per impostazione predefinita.

Ora ricevo sempre un errore sul mio server di produzione poiché carico tutti i file lib con caricamento automatico nel file application.rb .

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

Per ora, ho impostato config.enable_dependency_loading su true ma mi chiedo se c’è una soluzione migliore a questo. Ci deve essere una ragione per cui l’Autoloading è disabilitato in produzione di default.

Il mio elenco di modifiche dopo il passaggio a Rails 5:

  1. Posiziona lib dir app perché tutto il codice all’interno dell’app viene caricato automaticamente in dev e eager caricato in prod e, soprattutto, viene eseguito automaticamente con lo sviluppo automatico in modo da non dover riavviare il server ogni volta che si apportano modifiche.
  2. Rimuovi qualsiasi istruzione require che punta alle tue classi all’interno di lib perché sono tutte autoloaded comunque se la loro denominazione file / dir è corretta, e se lasci require può rompere il autoregamento automatico. Maggiori informazioni qui
  3. config.eager_load = true in tutti gli ambienti per vedere con entusiasmo i problemi di caricamento del codice in dev.
  4. Usa Rails.application.eager_load! prima di giocare con i thread per evitare errori di “dipendenza circolare”.
  5. Se si dispone di estensioni ruby ​​/ rails, lasciare il codice nella vecchia directory lib e caricarlo manualmente dall’inizializzatore. Ciò assicurerà che le estensioni vengano caricate prima della tua ulteriore logica che può dipendere da essa:

     # 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 } 

Ho appena usato config.eager_load_paths invece di config.autoload_paths come menzionare akostadinov sul commento github: https://github.com/rails/rails/issues/13142#issuecomment-275492070

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

Funziona sullo sviluppo e sull'ambiente di produzione.

Grazie Johan per il suggerimento di sostituire #{Rails.root}/lib con Rails.root.join('lib') !

L’autocaricamento è disabilitato nell’ambiente di produzione a causa della sicurezza del thread. Grazie a @ Зелёный per il link.

Ho risolto questo problema memorizzando i file lib in una cartella lib nella mia directory app come raccomandato su Github . Ogni cartella nella cartella app viene caricata automaticamente da Rails.

Ci deve essere una ragione per cui l’Autoloading è disabilitato in produzione di default.

Ecco una lunga discussione su questo problema. https://github.com/rails/rails/issues/13142

Questo permette di avere lib autoreload e funziona anche in ambiente di produzione.

PS Ho cambiato la mia risposta, ora aggiunge ad entrambi i percorsi desiderosi di autoload, indipendentemente dall’ambiente, per consentire il lavoro anche in ambienti personalizzati (come stage)

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

Per chiunque abbia faticato con questo come me, non basta posizionare una directory sotto app/ . Sì, riceverai il caricamento automatico ma non il ricaricamento necessario , il che richiede che vengano soddisfatte le convenzioni di assegnazione dei nomi .

Inoltre, l’uso dell’inizializzatore per il caricamento della vecchia versione di libreria a livello di radice impedirà il caricamento della funzionalità durante lo sviluppo.

In un certo senso, ecco un approccio unificato in Rails 5 per centralizzare la configurazione di eger e autoload, nello stesso tempo aggiunge il percorso di caricamento automatico quando viene configurato il carico bisognoso altrimenti non sarà in grado di funzionare correttamente:

 # 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 ... 

Spostare la cartella lib in app ha aiutato a risolvere un problema, la mia API di Twitter non funzionava in produzione. Avevo “costante non inizializzato TwitterApi” e la mia API di Twitter era nella mia cartella lib. Ho avuto config.autoload_paths += Dir["#{Rails.root}/app/lib"] nel mio application.rb ma non ha funzionato prima di spostare la cartella.

Questo ha fatto il trucco