2011-12-13 14 views
9

मेरे पास रेल 3.0.x एप्लिकेशन है। मैं Gemfile का उपयोग किए बिना रनटाइम पर रत्न लोड करना चाहता हूं।रेल में रनटाइम पर मणि लोड हो रहा है 3

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

क्या किसी को पता है कि रेल में यह संभव है, शायद बंडलर एपीआई का उपयोग कर रहा है?

+0

जिज्ञासा से बाहर: आप यूज-केस समझा सकता है? यह मुझे स्पष्ट नहीं है कि आप ऐसा क्यों करना चाहते हैं। – nathanvda

+0

विचार मॉड्यूलर रेल एप्लिकेशन होना था जो रनटाइम पर इसके मॉड्यूल लोड करेगा। मैं निर्देशिका में मॉड्यूल/रत्न डालना चाहता था, एप्लिकेशन शुरू करना और लचीला होना चाहता था :) –

+0

ठीक है, मुझे लगता है कि आपके पास कुछ सामान्य रेल ऐप हैं जो आप क्लाइंट-साइट पर स्थापित करते हैं, और कुछ विकल्पों (शुल्क/लाइसेंस) के आधार पर इंस्टॉल करते हैं फ़ोल्डर में सही मॉड्यूल। लेकिन क्या होगा यदि आप सिर्फ Gemfile को संपादित करें, और इंस्टॉल बंडल करें? यह कम काम है, यह सुरक्षित है, और केवल संपादन/कॉन्फ़िगरेशन Gemfile संपादित कर रहा था। यही तो हम भी करते हैं। हम अपने स्वयं के "निजी" रत्नों के लिए अपने स्वयं के रत्नकर्ता की मेजबानी करते हैं। यदि कोई मॉड्यूल सक्षम या अक्षम है, तो हम सिर्फ Gemfile, बंडल को संपादित करें और पुनरारंभ करें। – nathanvda

उत्तर

6

तुम क्या करने की कोशिश कर रहे क्या खतरनाक है। यदि आपके प्रत्येक रेल इंजन भी रत्न हैं - तो उनके पास अन्य निर्भरताओं के साथ जेमफाइल भी होंगे, और बदले में अन्य निर्भरताएं होंगी। यदि आप बंडलर को उनको हल करने की अनुमति देते हैं, तो आपको रनटाइम पर कम समस्याएं होंगी।

यहां यह है कि आप इसे बिना किसी हैक्स के बिना कैसे करेंगे। याद रखें कि आपका Gemfile सिर्फ रूबी कोड है, और आपके पास रत्न हो सकते हैं जो डिफ़ॉल्ट रूप से लोड नहीं होते हैं।

# In your Gemfile, add at the end: 
Dir[YOUR_RAILS_ENGINES_SUBFOLDER + "/*/*.gemspec"].each do |gemspec_file| 
    dir_name = File.dirname(gemspec_file) 
    gem_name = File.basename(gemspec_file, File.extname(gemspec_file)) 

    # sometimes "-" and "_" are used interchangeably in gems 
    # for e.g. gemspec_file is "engines/my-engine/my_engine.gemspec" 
    # dir_name will be engines/my-engine 
    # gem_name will be my_engine 

    # Register that engine as a dependency, *without* being required 
    gem gem_name, :path => dir_name, :require => false 

    # e.g. this is similar to saying 
    # gem 'my_engine', :path => 'engines/my-engine', :require => false 
end 

अब आपके सभी गतिशील रेल इंजन मणि निर्भरताओं के रूप में पंजीकृत हैं। बंडलर उन्हें और उनके सभी उप-निर्भरताओं को हल करेगा, इसलिए आपको किसी चीज़ के बारे में चिंता करने की ज़रूरत नहीं है। एप्लिकेशन चलाने से पहले bundle install चलाएं, या जब भी आप उस फ़ोल्डर में किसी भी इंजन को जोड़/हटा दें।

अच्छी बात यह है कि ये रत्न केवल पंजीकृत होंगे, और लोड नहीं होंगे। तो अपने उत्पादन कोड में, अब आप जो कुछ भी मणि है कि आप क्रम में चयन लोड कर सकते हैं बस कह require <your-engine-name>

संपादित करें द्वारा: अतिरिक्त कोड टिप्पणी

+1

अच्छा, मैंने 1.5 साल पहले इस सवाल से पूछा था और मैं रेल का उपयोग नहीं कर रहा हूं, लेकिन मुझे लगता है कि यह वही है जो मैं ढूंढ रहा था और यह वास्तव में काम कर सकता था। धन्यवाद –

+1

मैं ओपी नहीं हूं लेकिन मैंने इस प्रश्न के लिए बक्षीस शुरू किया था। सवाल के रूप में सवाल यह था कि कैसे स्टार्टअप पर नहीं, रनटाइम में इंजन को गतिशील रूप से लोड करना है। यदि स्टार्टअप पर लोड करना पर्याप्त था तो boot.rb से Bundler.load_gemspec को कॉल करने का एक आसान तरीका होगा। –

+0

यह कोड रत्न * गतिशील * लोड करने से बहुत दूर है। – Nowaker

0

इस प्रयास करें:

Bundler.with_clean_env do 
    # require gems... 
end 
+0

मैंने पहले कोशिश की और मुझे नहीं पता कि मुझे कुछ याद आ रहा है, लेकिन अगर मैं इस लाइन को 'boot.rb' में जोड़ता हूं तो मुझे त्रुटि मिलती है:' my_gem 'बंडल का हिस्सा नहीं है। इसे Gemfile में जोड़ें। –

+0

लिखने से आपका क्या मतलब है: '# जवाहरात की आवश्यकता है ... ', शायद यही वह है जो मुझे याद आ रही है? –

संबंधित मुद्दे