Rails 5: carica i file lib in produzione


128

Ho aggiornato una delle mie app da Rails 4.2.6 a Rails 5.0.0. La Guida all'aggiornamento afferma che la funzione Autoload è 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 application.rbfile.

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

Per il momento, ho impostato il config.enable_dependency_loadingper truema mi chiedo se c'è una soluzione migliore a questo. Ci deve essere un motivo per cui il caricamento automatico è disabilitato in produzione per impostazione predefinita.


cosa folle e i documenti ti dicono ancora di fare auto_load. Ero molto confuso su cosa non andasse nell'ambiente di produzione di una nuova app. E da quando ho iniziato a studiare con Rails 5 non ho letto la guida alla migrazione. Ho presentato un problema con il documento per sperare di risolverlo: github.com/rails/rails/issues/27268
akostadinov il

1
sorprendentemente, ho due file in libdir, un file è facilmente disponibile in Runtime, ma un altro deve essere richiesto manualmente: D
illusionista

@Tobias Con quale soluzione sei arrivato?
geoboy,

@geoboy I raggruppo il codice (come Validators) nelle cartelle direttamente nella directory app / poiché il codice viene caricato automaticamente.
Tobias,

si tratta di una corretta e il percorso del file di definizione della classe qui è ciò che il lavoro per me in Rails 5.2: Percorso file: app/services/paylinx/paylinx_service.rbDefinizione Classe: module Paylinx class PaylinxService end end. Ho provato queste autoload_pathscose. non funziona per me.
NamNamNam

Risposte:


161

Il mio elenco di modifiche dopo essere passato a Rails 5:

  1. Inserisci libdir in appperché tutto il codice all'interno dell'app viene caricato automaticamente in dev e impazientemente caricato in prod e, soprattutto, viene caricato automaticamente nello sviluppo in modo da non dover riavviare il server ogni volta che apporti modifiche.
  2. Rimuovi tutte le requireistruzioni che puntano alle tue classi all'interno libperché tutte sono comunque caricate automaticamente se il loro nome file / dir è corretto e se lasci le requireistruzioni può interrompere il caricamento automatico. Maggiori informazioni qui
  3. Impostare config.eager_load = truein tutti gli ambienti per vedere i problemi di caricamento del codice con entusiasmo in dev.
  4. Utilizzare 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 quel codice nella vecchia libdirectory e caricarli 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 }

8
Quindi come si usa la libcartella ora? Voglio dire spostare libdir in appdir sembra un po 'come una soluzione alternativa.
Martin Svoboda,

3
/app/lib/ha inserito un file / classe e NON si carica automaticamente. testato su rotaie 5.1, nuovo progetto
Tim Kretschmer,

29
Vale la pena notare che è necessario interrompere la primavera. Ho spostato tutto in app / lib / e poi ho perso un po 'di tempo chiedendomi perché non riuscivo ancora a usare le mie lezioni dalla console. spring stop ftw :)
jacklin,

1
Dove andrebbe la seguente rigaRails.application.eager_load!
Steven Aguilar l'

1
Questo potrebbe funzionare ma non è la soluzione migliore. Anche la struttura delle cartelle è semantica. Le cose libhanno una vicinanza al progetto diversa rispetto alle cose nella appdirectory. Molte delle altre risposte sono migliori di questa.
CWitty,

84

Ho appena usato config.eager_load_pathsinvece di config.autoload_pathsmenzionare akostadinov sul commento di 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 su ambiente di sviluppo e produzione.

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


3
Funziona come un fascino. La sintassi non mi è piaciuta, quindi l'ho cambiata in config.eager_load_paths << Rails.root.join('lib').
3limin4t0r,

2
Per me è stata la risposta migliore. Il mio progetto è iniziato da zero su Rails 5.2 e la cartella / lib era ancora creata fuori dalla cartella / app. Non ho visto un buon motivo per spostarlo.
Samir Haddad,

1
Sì, funziona! Sembra che gli sviluppatori di Rails si divertano davvero a causare problemi con il caricamento di lib: D alla prossima!
Damien Roche,

To Rails 5.2 utilizza config.eager_load_paths += [Rails.root.join('lib')]invece perché config.eager_load_pathsè un array congelato
William Wong Garay,

@WilliamWongGaray config.eager_load_paths è di sola lettura quando si tenta di modificarlo nell'inizializzatore. Quando aggiungi percorsi application.rb, funzionerà usando entrambi i metodi.
Michał Zalewski,

31

Il caricamento automatico è disabilitato nell'ambiente di produzione a causa della sicurezza del thread. Grazie a @ Зелёный per il link.

Ho risolto questo problema archiviando i file lib in una libcartella nella mia appdirectory come raccomandato su Github . Ogni cartella nella appcartella viene caricata automaticamente da Rails.


6
Se non vuoi approfondire il lungo thread di discussione su Github, puoi trovare una spiegazione dettagliata qui: collectiveidea.com/blog/archives/2016/07/22/…
Ernest

7
Ho usato config.eager_load_paths << "#{Rails.root}/lib", è meglio IMO per seguire la struttura dell'app delle rotaie raccomandata.
Akostadinov,

2
L'inserimento della lib in app/libè raccomandato dai membri di rails github.com/rails/rails/issues/13142#issuecomment-275549669
eXa

4
Ciò rovina completamente lo scopo di lib. Aspetterei che sia affascinato da tenderlove o DHH. Nel frattempo, consiglierei (personalmente) di attenermi alla risposta di @Lev Lukomsky.
Josh Brody,

@JoshBrody La mia opinione ora è che non dovresti aver bisogno della /libdirectory. Le librerie di terze parti sono per lo più gemme e in caso contrario dovrebbe essere creata una gemma. Per altri file, creo cartelle specifiche nella /appdirectory. Per esempio validators.
Tobias,


12

Ciò consente di eseguire il lib autoreload e funziona anche in ambiente di produzione.

PS Ho cambiato la mia risposta, ora si aggiunge a entrambi i percorsi desiderosi e automatici, indipendentemente dall'ambiente, per consentire il lavoro anche in ambienti personalizzati (come il palcoscenico)

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

2
Potresti espandere il motivo per cui questo risolve il problema?
Stuart.Sklinar,

@ Stuart.Sklinar questo permette di avere il lib autoreload e funziona anche in ambiente di produzione. PS Ho cambiato la mia risposta, ora si aggiunge a entrambi i percorsi desiderosi e automatici, indipendentemente dall'ambiente, per consentire il lavoro anche in ambienti personalizzati (come il palcoscenico)
srghma,

1
Potresti espandere (nella tua risposta)? La risposta del solo codice non aiuta davvero nessuno a capire perché dovrebbe essere fatto "in quel modo" - dovrei aggiungere che non sono un sviluppatore di Ruby, sto solo aiutando a chiarire SO. L'aggiunta di alcuni commenti a una "risposta solo in codice" darebbe un contesto reale.
Stuart.Sklinar,

1
@Stuart.Sklinar sicuro
srghma

6

Basta cambiare config.autoload_paths in config.eager_load_paths nel file config / application.rb. Perché in rails 5 il caricamento automatico è disabilitato per ambiente di produzione per impostazione predefinita. Per maggiori dettagli segui il link .

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

Funziona sia per lo sviluppo ambientale che per la produzione.


4

In un certo senso, ecco un approccio unificato in Rails 5 per centralizzare la configurazione di eager e caricamento automatico, allo stesso tempo aggiunge il percorso di caricamento automatico richiesto ogni volta che il carico di eager è configurato, 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
...


0

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

Questo ha funzionato


-6

per riassumere la risposta di Lev: è mv lib appstato sufficiente avere tutto il mio libcodice caricato automaticamente / ricaricato automaticamente.

(rails 6.0.0beta3 ma dovrebbe funzionare bene anche su rails 5.x)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.