Rails 5: Üretimde lib dosyalarını yükle


128

Uygulamalarımdan birini Rails 4.2.6'dan Rails 5.0.0'a yükselttim. Yükseltme Kılavuzu , Otomatik Yükleme özelliğinin artık üretimde varsayılan olarak devre dışı bırakıldığını söylüyor.

Artık tüm lib dosyalarını application.rbdosyaya autoload ile yüklediğim için üretim sunucumda her zaman bir hata alıyorum .

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

Şimdilik, ben kurdum config.enable_dependency_loadingetmek trueama bu daha iyi bir çözüm olup olmadığını merak ediyorum. Üretimde varsayılan olarak Otomatik Yüklemenin devre dışı bırakılmasının bir nedeni olmalıdır.


çılgın bir şey ve dokümanlar hala otomatik yükleme yapmanızı söylüyor. Yeni bir uygulama için üretim ortamında neyin yanlış gittiğini çok karıştırdım. Ve Rails 5 ile öğrenmeye başladığımdan beri geçiş kılavuzunu okumadım. Bu sorunun çözülmesini ummak
akostadinov

1
şaşırtıcı bir şekilde, dizinde iki libdosyam var, bir dosya Runtime'da kolayca kullanılabilir, ancak bir başkası manuel olarak gerekli olmalı: D
illusionist

@Tobias Hangi çözümü buldunuz?
geoboy

@geoboy Kod Validatorsotomatik olarak yüklendiğinden, doğrudan app / dizindeki klasörlerde grup kodu (gibi ).
Tobias

Mesele doğru dosya yolu ve sınıf tanımı Dosya yolu: Raylar 5.2 ne benim için iştir burada app/services/paylinx/paylinx_service.rbSınıf tanımı: module Paylinx class PaylinxService end end. Bunları denedim autoload_paths. benim için çalışmıyor.
NamNamNam

Yanıtlar:


161

Rails 5'e geçtikten sonraki değişiklik listem:

  1. Yeri libiçine dir appapp içindeki tüm kod, çünkü otomatik yüklenmesi dev ve içinde yüklü istekli ve en önemlisi eşya ve autoreloaded Eğer sunucusunu değişiklik yapmak her zaman yeniden zorunda kalmamak gelişiminde.
  2. requireİçindeki kendi sınıflarınızı gösteren tüm ifadeleri kaldırın , libçünkü dosya / dizin adları doğruysa hepsi otomatik olarak yüklenir ve requireifadelerden ayrılırsanız otomatik yeniden yüklemeyi bozabilir. Daha fazla bilgi burada
  3. Ayarlamak config.eager_load = trueDev'de kod yükleme sorunlarını hevesle görmek için tüm ortamlarda .
  4. Rails.application.eager_load!"Döngüsel bağımlılık" hatalarını önlemek için dizilerle oynamadan önce kullanın .
  5. Herhangi bir ruby ​​/ rails uzantınız varsa, bu kodu eski libdizinde bırakın ve başlatıcıdan manuel olarak yükleyin. Bu, uzantıların, ona bağlı olabilecek diğer mantığınızdan önce yüklenmesini sağlayacaktır:

    # 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
Peki libşimdi klasör nasıl kullanılıyor ? Demek istediğim lib, appdir dizine taşımak bir çeşit geçici çözüm gibi görünüyor.
Martin Svoboda

3
/app/lib/bir dosya / sınıf yerleştirildi ve bu otomatik yükleme DEĞİLDİR. 5.1 raylarda test edildi, yeni proje
Tim Kretschmer

29
Baharı durdurmanız gerektiğini belirtmekte fayda var. Her şeyi app / lib / 'e taşıdım ve sonra konsoldaki derslerimi neden hala kullanamadığımı merak ederek biraz zaman harcadım. spring stop ftw :)
jacklin

1
Aşağıdaki satır nereye giderRails.application.eager_load!
Steven Aguilar

1
Bu işe yarayabilir, ancak en iyi çözüm değildir. Klasör yapısı da anlamsaldır. İçinde şeyler libfarklı olması şeylere daha projeye yakınlık algılanan appdizine. Diğer cevaplardan birkaçı bundan daha iyidir.
CWitty

84

Sadece kullandım config.eager_load_pathsconfig.autoload_pathsGithub yorumunda akostadinov'dan bahsetmek yerine : https://github.com/rails/rails/issues/13142#issuecomment-275492070

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

Geliştirme ve üretim ortamı üzerinde çalışır.

Teşekkür Johan öneri değiştirmesinin #{Rails.root}/libile Rails.root.join('lib')!


3
Tıkır tıkır çalışıyor. Sözdizimini beğenmedim, bu yüzden olarak değiştirdim config.eager_load_paths << Rails.root.join('lib').
3limin4t0r

2
Bana göre bu en iyi cevaptı. Projem Rails 5.2'de sıfırdan başladı ve / lib klasörü hala / app klasörünün dışında oluşturuldu. Onu taşımak için iyi bir neden görmedim.
Samir Haddad

1
Evet, bu işe yarıyor! Görünüşe göre Rails geliştiricileri lib yükleme sorunlarına neden olmaktan gerçekten keyif alıyor: Bir dahaki sefere D!
Damien Roche

To Rails 5.2 config.eager_load_paths += [Rails.root.join('lib')]yerine config.eager_load_pathsdonmuş bir dizi kullanıyor
William Wong Garay

@WilliamWongGaray config.eager_load_paths, onu başlatıcıda değiştirmeye çalıştığınızda salt okunurdur. Yolları eklediğinizde application.rb, her iki yöntemi de kullanarak çalışacaktır.
Michal Zalewski

31

İş parçacığı güvenliği nedeniyle üretim ortamında otomatik yükleme devre dışı bırakıldı. Bağlantı için @ Зелёный'e teşekkür ederiz.

Bu sorunu, lib dosyalarını Github'da önerildiği şekilde dizinimdeki bir libklasörde saklayarak çözdüm . Klasördeki her klasör, Rails tarafından otomatik olarak yüklenir.appapp


6
Github'daki uzun tartışma dizisini incelemek istemiyorsanız, burada ayrıntılı açıklamaları bulabilirsiniz: Collectiveidea.com/blog/archives/2016/07/22/…
Ernest

7
Ben kullandım config.eager_load_paths << "#{Rails.root}/lib", bu önerilen raylar uygulama yapısını takip etmek için daha iyi bir IMO.
akostadinov

2
İçinde lib koymak app/libraylar tarafından tavsiye edilmektedir üyeleri github.com/rails/rails/issues/13142#issuecomment-275549669
EXA

4
Bu, amacının ne olduğunu tamamen mahvediyor lib. Bonfile veya DHH'nin gelmesini beklerdim. Bu arada, (şahsen) @Lev Lukomsky'nin cevabına bağlı kalmanızı tavsiye ederim.
Josh Brody

@JoshBrody Benim fikrim, /libdizine hiç ihtiyacınız olmaması gerektiğidir . Üçüncü parti kütüphaneler çoğu zaman değerli taşlardır ve eğer yoksa bir mücevher yaratılmış olmalıdır. Diğer dosyalar için /appdizinde belirli klasörler oluşturuyorum . Örneğin validators.
Tobias


12

Bu, lib otomatik yeniden yüklemesine izin verir ve üretim ortamında da çalışır.

Not: Cevabımı değiştirdim, şimdi özel ortamlarda da çalışmaya izin vermek için ortamdan bağımsız olarak her iki hevesli otomatik yükleme yoluna da ekliyor (sahne gibi)

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

2
Bunun neden sorunu çözdüğünü açıklayabilir misiniz?
Stuart.Sklinar

@ Stuart.Sklinar bu, lib autoreload'a izin verir ve üretim ortamında da çalışır. Not: Cevabımı değiştirdim, şimdi özel ortamlarda (sahne gibi) çalışmaya izin vermek için ortamdan bağımsız olarak her iki hevesli otomatik yükleme yoluna da ekliyor
srghma

1
(Cevabınıza göre) genişletebilir misiniz? Yalnızca kod yanıtları, kimsenin bunun neden "bu şekilde" yapılması gerektiğini anlamasına gerçekten yardımcı olmuyor - ben bir Ruby geliştiricisi olmadığımı eklemeliyim, sadece SO'nun temizlenmesine yardımcı oluyor. Bir "yalnızca kod yanıtına" biraz yorum eklemek, ona gerçek bir bağlam kazandırır.
Stuart.Sklinar

1
@ Stuart.Sklinar sure
srghma

6

Config / application.rb dosyasındaki config.autoload_paths öğesini config.eager_load_paths olarak değiştirin . Çünkü raylarda üretim ortamı için 5 otomatik yükleme varsayılan olarak devre dışı bırakılmıştır. Daha fazla ayrıntı için lütfen bağlantıyı takip edin .

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

Hem çevre geliştirme hem de üretim için çalışır.


4

Bir anlamda burada, istekli ve otomatik yükleme yapılandırmasını merkezileştirmek için Rails 5'te birleşik bir yaklaşım vardır, aynı zamanda istekli yük yapılandırıldığında gerekli otomatik yükleme yolunu ekler, aksi takdirde doğru şekilde çalışamaz:

# 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

Lib klasörünü uygulamaya taşımak bir sorunu çözmeye yardımcı oldu, Twitter API'm üretimde çalışmıyordu. "Başlatılmamış sabit TwitterApi" vardı ve Twitter API'm lib klasörümdeydi. sahiptimconfig.autoload_paths += Dir["#{Rails.root}/app/lib"]Application.rb dosyamda , ancak klasörü taşımadan önce çalışmadı.

Bu hile yaptı


-6

Lev'in cevabını özetlemek gerekirse: mv lib appbenim her şeyime sahip olmak yeterliydilib kodumun otomatik olarak yüklenmesi / otomatik olarak yeniden yüklenmesi .

(6.0.0beta3 raylar ancak 5.x raylarda da iyi çalışmalıdır)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.