Zaktualizowałem jedną z moich aplikacji z Rails 4.2.6 do Rails 5.0.0. Upgrade Przewodnik mówi, że funkcja Autoload jest teraz wyłączone w produkcji domyślnie.
Teraz zawsze pojawia się błąd na moim serwerze produkcyjnym, ponieważ ładuję wszystkie pliki lib z automatycznym ładowaniem w application.rb
pliku.
module MyApp
class Application < Rails::Application
config.autoload_paths += %W( lib/ )
end
end
Na razie mam ustawić config.enable_dependency_loading
aby true
ale zastanawiam się, czy istnieje lepsze rozwiązanie tego. Musi istnieć powód, dla którego automatyczne ładowanie jest domyślnie wyłączone w środowisku produkcyjnym.
lib
dir, jeden plik jest łatwo dostępny w Runtime, ale inny musi być wymagany ręcznie: DValidators
) w folderach bezpośrednio w katalogu aplikacji /, ponieważ kod jest ładowany automatycznie.app/services/paylinx/paylinx_service.rb
definicja klasy:module Paylinx class PaylinxService end end
. Próbowałem tychautoload_paths
rzeczy. nie działa dla mnie.Odpowiedzi:
Moja lista zmian po przejściu na Rails 5:
lib
dir w,app
ponieważ cały kod wewnątrz aplikacji jest automatycznie ładowany w wersji deweloperskiej i chętnie ładowany w wersji produkcyjnej, a co najważniejsze jest automatycznie ładowany podczas programowania, więc nie musisz ponownie uruchamiać serwera za każdym razem, gdy wprowadzasz zmiany.require
instrukcje wskazujące na twoje własne klasy wewnątrz,lib
ponieważ i tak są one automatycznie ładowane, jeśli ich nazewnictwo plików / katalogów jest poprawne, a jeśli zostawiszrequire
instrukcje, może to przerwać automatyczne ładowanie. Więcej informacji tutajconfig.eager_load = true
we wszystkich środowiskach, aby zobaczyć problemy z ładowaniem kodu w dev.Rails.application.eager_load!
przed rozpoczęciem gry z wątkami, aby uniknąć błędów „zależności cyklicznych”.Jeśli masz jakieś rozszerzenia ruby / rails, zostaw ten kod w starym
lib
katalogu i załaduj je ręcznie z inicjatora. Zapewni to, że rozszerzenia zostaną załadowane przed dalszą logiką, która może na nim polegać:# 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 }
źródło
lib
teraz używa się folderu? Chodzi mi o to, że przeniesienielib
dir doapp
dir wydaje się być obejściem./app/lib/
umieścił plik / klasę i NIE ładuje się automatycznie. testowany na szynach 5.1, nowy projektRails.application.eager_load!
lib
mają inną postrzeganą bliskość do projektu niż rzeczy wapp
katalogu. Kilka innych odpowiedzi jest lepszych niż ta.Po prostu użyłem
config.eager_load_paths
zamiastconfig.autoload_paths
jak wspomnieć akostadinov w komentarzu na 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')
Działa na środowisku deweloperskim i produkcyjnym.
Dzięki Johan dla propozycja zastąpienia
#{Rails.root}/lib
zRails.root.join('lib')
!źródło
config.eager_load_paths << Rails.root.join('lib')
.config.eager_load_paths += [Rails.root.join('lib')]
zamiast tego, ponieważconfig.eager_load_paths
jest zamrożoną tablicąapplication.rb
będzie działać przy użyciu obu metod.Automatyczne ładowanie jest wyłączone w środowisku produkcyjnym ze względu na bezpieczeństwo wątków. Dziękuję @ Зелёный za link.
Rozwiązałem ten problem, przechowując pliki lib w
lib
folderze w moimapp
katalogu, zgodnie z zaleceniami na Github . Każdy folder wapp
folderze jest automatycznie ładowany przez Railsy.źródło
config.eager_load_paths << "#{Rails.root}/lib"
, to lepsze IMO, aby podążać za zalecaną strukturą aplikacji rails.app/lib
jest zalecane przez członków rails github.com/rails/rails/issues/13142#issuecomment-275549669lib
. Czekałbym, aż tuczna miłość lub DHH się włączy. W międzyczasie (osobiście) radziłbym trzymać się odpowiedzi @Lev Lukomsky./lib
katalogu. Biblioteki stron trzecich są w większości klejnotami, a jeśli nie, powinny zostać utworzone. Dla innych plików tworzę określone foldery w/app
katalogu. Na przykładvalidators
.Oto długa dyskusja na ten temat. https://github.com/rails/rails/issues/13142
źródło
Pozwala to na automatyczne ładowanie lib i działa również w środowisku produkcyjnym.
PS Zmieniłem odpowiedź, teraz dodaje się do obu chętnych - automatyczne ładowanie ścieżek, niezależnie od środowiska, aby umożliwić pracę również w niestandardowych środowiskach (takich jak stage)
# config/initializers/load_lib.rb ... config.eager_load_paths << Rails.root.join('lib') config.autoload_paths << Rails.root.join('lib') ...
źródło
Po prostu zmień config.autoload_paths na config.eager_load_paths w pliku config / application.rb. Ponieważ w rails 5 automatyczne ładowanie jest domyślnie wyłączone dla środowiska produkcyjnego. Aby uzyskać więcej informacji, kliknij łącze .
#config.autoload_paths << "#{Rails.root}/lib" config.eager_load_paths << Rails.root.join('lib')
Działa zarówno na potrzeby rozwoju środowiska, jak i produkcji.
źródło
W pewnym sensie tutaj jest ujednolicone podejście w Railsach 5 do scentralizowania konfiguracji przyspieszonego i automatycznego ładowania, jednocześnie dodaje wymaganą ścieżkę automatycznego ładowania, gdy zostanie skonfigurowane pożądane ładowanie, w przeciwnym razie nie będzie w stanie działać poprawnie:
# 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 ...
źródło
Dla każdego, kto zmagał się z tym, tak jak ja, nie wystarczy po prostu umieścić katalog pod
app/
. Tak, otrzymasz automatyczne ładowanie, ale nie będzie to konieczne ponowne ładowanie, co wymaga przestrzegania konwencji przestrzeni nazw .Ponadto użycie inicjalizatora do ładowania starego poziomu roota
lib
zapobiegnie przeładowaniu funkcji podczas programowania.źródło
Przeniesienie folderu lib do aplikacji pomogło rozwiązać problem, mój interfejs API na Twitterze nie działał w środowisku produkcyjnym. Miałem „niezainicjowaną stałą TwitterApi”, a moje API Twittera znajdowało się w folderze lib. Miałem
config.autoload_paths += Dir["#{Rails.root}/app/lib"]
plik application.rb, ale nie działał przed przeniesieniem folderu.To załatwiło sprawę
źródło
podsumowując odpowiedź Lwa:
mv lib app
wystarczyło, aby cały mójlib
kod był automatycznie ładowany / ponownie ładowany.(szyny 6.0.0beta3, ale powinny działać dobrze również na szynach 5.x)
źródło