रेल 5: उत्पादन में कामेच्छा फ़ाइलें लोड करें


128

मैंने अपने एक ऐप को Rails 4.2.6 से Rails 5.0.0 तक अपग्रेड किया है। अपग्रेड मार्गदर्शिका का कहना है, कि AutoLoad सुविधा अब डिफ़ॉल्ट रूप से उत्पादन में अक्षम है।

अब मुझे हमेशा अपने प्रोडक्शन सर्वर पर एक त्रुटि मिलती है क्योंकि मैं फाइल में ऑटोलॉड के साथ सभी काम करने वाली फाइलों को लोड करता हूं application.rb

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

अभी के लिए, मैंने इसे सेट कर config.enable_dependency_loadingदिया है, trueलेकिन मुझे आश्चर्य है कि क्या इसका कोई बेहतर समाधान है। एक कारण होना चाहिए कि डिफ़ॉल्ट रूप से ऑटोलडिंग उत्पादन में अक्षम है।


पागल बात, और डॉक्स अभी भी आपको auto_load करने के लिए कहते हैं। मैं बहुत उलझन में था कि नए ऐप के लिए प्रोडक्शन एनवी में क्या गलत हो रहा है। और जब से मैंने रेल 5 के साथ सीखना शुरू किया, मैंने माइग्रेशन गाइड नहीं पढ़ा। मैंने उम्मीद के साथ इसे हल करने के लिए एक डॉक्टर मुद्दा दायर किया: github.com/rails/rails/issues/27268
akostadinov

1
आश्चर्यजनक रूप से, मेरे पास libdir में दो फाइलें हैं , एक फ़ाइल रनटाइम में आसानी से उपलब्ध है, लेकिन दूसरे को मैन्युअल रूप से आवश्यक होना चाहिए: D
भ्रम

@ टोबियास आपके साथ क्या समाधान था?
जियोबॉय

@geoboy I समूह कोड (जैसे Validators) फ़ोल्डरों में सीधे ऐप / डायरेक्टरी में कोड के बाद से ऑटो लोड है।
टोबियास

यह उचित फ़ाइल पथ और वर्ग परिभाषा के बारे में है यहाँ रेल 5.2 में मेरे लिए क्या काम है: फ़ाइल पथ: app/services/paylinx/paylinx_service.rbवर्ग परिभाषा module Paylinx class PaylinxService end end:। मैंने ये autoload_pathsसामान आजमाया । मेरे लिए काम नहीं करता है।
नामनमं

जवाबों:


161

रेल 5 पर जाने के बाद परिवर्तनों की मेरी सूची:

  1. प्लेस libमें dir appक्योंकि एप्लिकेशन के अंदर सभी कोड है autoloaded देव में और उत्सुक लोड prod में और सबसे महत्वपूर्ण बात है autoreloaded विकास में तो तुम सर्वर हर बार जब आप परिवर्तन कर पुनः आरंभ करने की जरूरत नहीं है।
  2. requireअपने स्वयं के वर्गों की ओर इशारा करते हुए किसी भी बयान को हटा दें libक्योंकि वे सभी वैसे भी ऑटो- 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
यह ध्यान देने योग्य है कि आपको वसंत को रोकने की आवश्यकता है। मैंने सब कुछ ऐप / लिब / में स्थानांतरित कर दिया और फिर थोड़ा समय बर्बाद करते हुए सोचा कि मैं अभी भी कंसोल से अपनी कक्षाओं का उपयोग क्यों नहीं कर सकता। स्प्रिंग स्टॉप ftw :)
जैकलीन

1
निम्नलिखित पंक्ति कहाँ जाएगीRails.application.eager_load!
स्टीवन एगुइलर

1
यह काम कर सकता है लेकिन यह सबसे अच्छा समाधान नहीं है। फ़ोल्डर संरचना अर्थपूर्ण होने के साथ-साथ है। में हालात libएक अलग राशि में चीजों की तुलना में परियोजना से निकटता कथित appनिर्देशिका। अन्य उत्तरों में से कई इस से बेहतर हैं।
सीडब्ल्यूटीटी

84

मैं सिर्फ github टिप्पणी पर akostadinov उल्लेख config.eager_load_pathsकी config.autoload_pathsतरह इस्तेमाल किया : https://github.com/rails/rails/issues/13142#issuecomment-275492070

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

यह विकास और उत्पादन पर्यावरण पर काम करता है।

सुझाव के साथ बदलने के लिए धन्यवाद जोहान !#{Rails.root}/libRails.root.join('lib')


3
एक जादू की तरह काम करता है। मुझे सिंटैक्स पसंद नहीं आया इसलिए इसे बदल दिया config.eager_load_paths << Rails.root.join('lib')
3limin4t0r

2
मेरे लिए वह सबसे अच्छा जवाब था। मेरी परियोजना खरोंच से रेल 5.2 पर शुरू हुई और फ़ोल्डर / लीबिल अभी भी / ऐप फ़ोल्डर के बाहर बनाई गई थी। मुझे इसे स्थानांतरित करने का एक अच्छा कारण नहीं दिख रहा था।
समीर हदद

1
हाँ, यह काम करता है! लगता है रेल देवता वास्तव में काम का बोझ बढ़ाने के मुद्दों का आनंद लेते हैं: अगली बार तक डी!
डेमियन रोश

रेल्स के config.eager_load_paths += [Rails.root.join('lib')]बजाय 5.2 का उपयोग करता है क्योंकि config.eager_load_pathsएक जमे हुए सरणी है
विलियम वोंग गारे

@WilliamWongGaray config.eager_load_paths केवल तभी पढ़ा जाता है जब आप इसे इनिलाइज़र में संशोधित करने का प्रयास करते हैं। जब आप application.rbइसमें पथ जोड़ते हैं तो दोनों विधियों का उपयोग करके काम करेंगे।
मीकल ज़ाल्स्की

31

थ्रेड सुरक्षा की वजह से ऑटोलोडिंग उत्पादन वातावरण में अक्षम है। लिंक के लिए @ ёелёный को धन्यवाद।

मैंने libअपनी appनिर्देशिका में एक फ़ोल्डर में लिबास फ़ाइलों को संग्रहीत करके इस समस्या को हल किया, जैसा कि गितुब पर अनुशंसित है । फ़ोल्डर में प्रत्येक फ़ोल्डर appरेल द्वारा स्वचालित रूप से लोड हो जाता है।


6
यदि आप गितुब पर लंबे चर्चा सूत्र के माध्यम से खुदाई नहीं करना चाहते हैं, तो आप यहां पर आसुत स्पष्टीकरण पा सकते हैं: collectiveidea.com/blog/archives/2016/07/22/…
अर्नेस्ट

7
मैंने इस्तेमाल किया config.eager_load_paths << "#{Rails.root}/lib", अनुशंसित रेल एप्लिकेशन संरचना का पालन करने के लिए बेहतर आईएमओ है।
akostadinov

2
में lib लाना app/libरेल द्वारा की सिफारिश की है सदस्यों github.com/rails/rails/issues/13142#issuecomment-275549669
EXA

4
यह पूरी तरह से बर्बाद कर देता है कि इसका उद्देश्य क्या libहै। मैं टेंडरलॉव या डीएचएच के लिए इंतजार करना चाहता हूं। इस बीच, मैं (व्यक्तिगत रूप से) @ ल्वे लुकोम्स्की के जवाब के साथ चिपके रहने की सलाह देता हूं।
जोश ब्रॉडी

@JoshBrody मेरी राय अब यह है कि आपको /libनिर्देशिका बिल्कुल नहीं चाहिए । थर्ड पार्टी लिबास ज्यादातर समय रत्नों का होता है और यदि नहीं तो रत्नों की रचना होनी चाहिए। अन्य फ़ाइलों के लिए, मैं /appनिर्देशिका में विशिष्ट फ़ोल्डर बनाता हूं । उदाहरण के लिए validators
तोबियास

22

एक कारण होना चाहिए कि डिफ़ॉल्ट रूप से ऑटोलडिंग उत्पादन में अक्षम है।

यहां इस मुद्दे पर एक लंबी चर्चा है। https://github.com/rails/rails/issues/13142


1
यह चर्चा सबसे अच्छी है, हालांकि एक लंबा पढ़ा गया, उस विषय पर जानकारी का स्रोत जो मैंने भर में आया है।
जेसन

12

यह काम करने की अनुमति देता है ऑटोरैलोएड, और उत्पादन वातावरण में भी काम करता है।

PS मैंने अपना उत्तर बदल दिया है, अब यह उत्सुक दोनों को जोड़ता है- एक ऑटोलॉड पथ, पर्यावरण की परवाह किए बिना, कस्टम वातावरण में भी काम करने की अनुमति देने के लिए (जैसे चरण)

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

2
क्या आप इस बात का विस्तार कर सकते हैं कि यह समस्या क्यों ठीक करता है?
स्टुअर्ट।सलिनार

@ Stuart.Sklinar यह काम करने की अनुमति देता है autoreload, और उत्पादन वातावरण में भी काम करता है। PS मैंने अपना उत्तर बदल दिया है, अब यह उत्सुक दोनों को जोड़ता है- एक ऑटोलॉड पथ, पर्यावरण की परवाह किए बिना, कस्टम वातावरण में भी काम करने की अनुमति देने के लिए (जैसे मंच)
srghma

1
क्या आप विस्तार कर सकते हैं (आपके उत्तर में)? कोड केवल उत्तर देता है वास्तव में किसी को यह समझने में मदद नहीं करता है कि इसे "इस तरह" क्यों किया जाना चाहिए - मुझे यह जोड़ना चाहिए कि मैं रूबी देव नहीं हूं, बस एसओ को स्पष्ट करने में मदद कर रहा हूं। कुछ टिप्पणियों को "केवल कोड का जवाब दें" से जोड़ने से कुछ वास्तविक संदर्भ मिलेंगे।
स्टुअर्ट। स्क्लिनार

1
@ स्टुअर्ट.सलिनर सुनिश्चित
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

कुछ अर्थों में, उत्सुक और ऑटोलॉड कॉन्फ़िगरेशन को केंद्रीयकृत करने के लिए रेल 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

ऐप में काम करने के लिए लेबर फोल्डर को ले जाने से समस्या का समाधान होता है, मेरा ट्विटर एप उत्पादन में नहीं चलेगा। मेरे पास "अनइंस्टाल्ड कंटीन्यूअस ट्विटरएपीआई" था और मेरा ट्विटर एपीआई मेरे काम के फ़ोल्डर में था। मैं config.autoload_paths += Dir["#{Rails.root}/app/lib"]अपने आवेदन में था । आरबी लेकिन यह फ़ोल्डर को स्थानांतरित करने से पहले काम नहीं करता था।

यह चाल चली


-6

लेव के जवाब को संक्षेप में बताने के लिए: mv lib appमेरे सभी libकोड को ऑटो-लोड / ऑटो-रीलोडेड करने के लिए पर्याप्त था ।

(रेल 6.0.0beta3 लेकिन रेल पर ठीक काम करना चाहिए 5.x भी)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.