रेलगाड़ी 3.1: इंजन बनाम माउंटेबल ऐप


120

क्या कोई मुझे रेल इंजन और एक माउंटेबल ऐप के बीच के अंतर को समझने में मदद कर सकता है? रेल 3.1 में, आप "रेल नए प्लगइन _ __ " कमांड के साथ एक बना सकते हैं ।

rails plugin new forum --full        # Engine
rails plugin new forum --mountable   # Mountable App

आप एक बनाम दूसरे का उपयोग कब करना चाहेंगे? मुझे पता है कि आप एक रत्न के रूप में एक इंजन को पैकेज कर सकते हैं, एक के लिए। क्या यह माउंटेबल ऐप्स के मामले में नहीं है? और क्या अंतर हैं?

जवाबों:


143

मैंने निम्नलिखित पर ध्यान दिया है:

पूर्ण इंजन

पूर्ण इंजन के साथ, मूल अनुप्रयोग इंजन से मार्गों को इनहेरिट करता है। इसमें कुछ भी निर्दिष्ट करना आवश्यक नहीं है parent_app/config/routes.rb। जेमफाइल में मणि को निर्दिष्ट करना माता-पिता ऐप के लिए मॉडल, मार्ग आदि को इनहेरिट करने के लिए पर्याप्त है। इंजन रूट निम्नानुसार हैं:

# my_engine/config/routes.rb 
Rails.application.routes.draw do 
  # whatever 
end 

मॉडल, नियंत्रक आदि का कोई नाम स्थान नहीं, ये मूल आवेदन के लिए तुरंत सुलभ हैं।

माउंटेबल इंजन

इंजन का नाम स्थान डिफ़ॉल्ट रूप से अलग है:

# my_engine/lib/my_engine/engine.rb
module MyEngine 
  class Engine < Rails::Engine 
    isolate_namespace MyEngine 
  end 
end

एक माउंटेबल इंजन के साथ, मार्ग नामांकित हैं और मूल एप्लिकेशन एकल मार्ग के तहत इस कार्यक्षमता को बंडल कर सकता है:

# my_engine/config/routes.rb 
MyEngine::Engine.routes.draw do 
  #whatever 
end 

# parent_app/config/routes.rb 
ParentApp::Application.routes.draw do 
    mount MyEngine::Engine => "/engine", :as => "namespaced" 
end 

मॉडल, कंट्रोलर आदि को पेरेंट एप्लिकेशन से अलग किया जाता है - हालाँकि हेल्पर्स को आसानी से साझा किया जा सकता है।

ये मुख्य अंतर हैं जिन्हें मैंने देखा है। शायद वहाँ दूसरों रहे हैं? मैंने यहां पर पूछा है , लेकिन अभी तक प्रतिक्रिया नहीं मिली है।

मेरी धारणा यह है कि चूंकि एक पूर्ण इंजन स्वयं को मूल अनुप्रयोग से अलग नहीं करता है, इसलिए इसे मूल अनुप्रयोग से सटे स्टैंडअलोन अनुप्रयोग के रूप में उपयोग किया जाता है। मेरा मानना ​​है कि नाम में गड़बड़ी हो सकती है।

एक माउंटेबल इंजन का उपयोग उन स्थितियों में किया जा सकता है जहां आप नाम के टकराव से बचना चाहते हैं और मूल एप्लिकेशन में एक विशिष्ट मार्ग के तहत इंजन को बंडल करते हैं। उदाहरण के लिए, मैं ग्राहक सेवा के लिए डिज़ाइन किए गए अपने पहले इंजन के निर्माण पर काम कर रहा हूं। मूल एप्लिकेशन एकल रूट के तहत इसकी कार्यक्षमता को बंडल कर सकता है जैसे:

mount Cornerstone::Engine => "/cornerstone", :as => "help" 

अगर मैं अपनी धारणाओं में बंध जाता हूं, तो कृपया मुझे बताएं और मैं इस प्रतिक्रिया को ठीक करूंगा। मैंने यहाँ चीयर्स विषय के बारे में एक छोटा सा लेख बनाया है !


1
क्या माता-पिता ऐप के रूट पर एक माउंटेबल इंजन को कभी भी रूट / माउंट किया जा सकता है?
स्लीक 23

3
@JustinM आप कोशिश कर सकते हैं mount MyEngine::Engine => "/"। यह संसाधनों के लिए काम करता है, हो सकता है कि यह इंजन के लिए भी हो।
बेनोइट गैरेट

2
@astjohn आपके ब्लॉग के महान योग। लेकिन क्या यह दूसरा रास्ता नहीं होगा? क्या एक पूर्ण इंजन "अधूरा" होगा और काम करने के लिए मूल ऐप की आवश्यकता होगी, जबकि माउंटेबल इंजन स्टैंड-अलोन काम कर सकता है, क्योंकि यह मूल ऐप से "पृथक" है?
थियो स्कोलाडिस

39

दोनों विकल्प एक इंजन उत्पन्न करेंगे । अंतर यह है कि --mountableइंजन को एक पृथक नेमस्पेस में --fullबनाया जाएगा , जबकि एक इंजन बनाएगा जो मुख्य ऐप के नाम स्थान को साझा करेगा।

मतभेद 3 तरीकों से प्रकट होंगे:

1) इंजन वर्ग फ़ाइल कॉल करेगा isolate_namespace:

lib / my_full_engine / engine.rb:

module MyFullEngine
  class Engine < Rails::Engine
  end
end

lib / my_mountable_engine / engine.rb:

module MyMountableEngine
  class Engine < Rails::Engine
    isolate_namespace MyMountableEngine # --mountable option inserted this line
  end
end

2) इंजन की config/routes.rbफ़ाइल नाम स्थान पर होगी:

पूर्ण इंजन:

Rails.application.routes.draw do
end

घुड़सवार इंजन:

MyMountableEngine::Engine.routes.draw do
end

3) नियंत्रकों, सहायकों, विचारों और परिसंपत्तियों के लिए फ़ाइल संरचना नामांकित होगी:

ऐप / कंट्रोलर बनाएं / my_mountable_engine /application_controller.rb
ऐप बनाएं / हेल्पर्स / my_mountable_engine /application_helper.rb
ऐप बनाएं / मेलर्स ऐप
बनाएँ / ऐप / व्यूज़ बनाएँ / my_mountable_engine /application.html.erb
ऐप / एसेट इमेज / एप्लिकेशन इमेज / इमेज बनाएं।
ऐप / एसेट / स्टाइलशीट / my_mountable_engine /application.css
बनाएं ऐप / एसेट्स / javascripts / my_mountable_engine /application.js कॉन्फिगर / मार्गों को
बनाएँ। lib / my_mountable_engine.rb
lib / कार्य / my_mountable_engine.engine
बनाएं। .rb
lib / my_mountable_engine / engine.rb बनाएँ


व्याख्या

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

प्रलेखन मैंने देखा है का प्रत्येक भाग को दर्शाता है --mountableविकल्प, और वास्तव में मौजूदा बढ़त गाइड दृढ़ता से शामिल करने के लिए आप को प्रोत्साहित करती है isolate namespace- जो उपयोग यह कहते हुए एक ही है --mountableसे अधिक --full

अंत में शब्दावली भ्रम है: दुर्भाग्य rails plugin -hसे निम्नलिखित विवरण दिखाता है:

[--full] # परीक्षण के लिए बंडल रेल अनुप्रयोग के साथ एक रेल इंजन उत्पन्न करें
[- उल्लेखनीय] # जनरेट किए गए अलग-थलग करें

यह धारणा देता है कि आप --full"इंजन" बनाने के लिए उपयोग करते हैं और --mountable"माउंटेबल एप्लिकेशन" नामक कुछ और बनाने के लिए, जब वास्तव में वे दोनों इंजन होते हैं - एक नामस्थान और एक नहीं। यह भ्रम पैदा करने के लिए बाध्य है क्योंकि इंजन बनाने के इच्छुक उपयोगकर्ता यह मान लेंगे कि --fullयह अधिक प्रासंगिक विकल्प है।

निष्कर्ष

  • rails plugin new something --full= आपके ऐप के नेमस्पेस में इंजन। (आप क्यों?)
  • rails plugin new something --mountable= इसके नाम के साथ इंजन। (बहुत बढ़िया)

संदर्भ


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

2
@nathanvda - ठीक है, लेकिन मुझे लगता है कि यदि आप कई परियोजनाओं में कुछ साझा कर रहे हैं तो इसे वास्तव में नाम स्थान पर होना चाहिए, क्योंकि आप मूल रूप से इसे प्लगइन के रूप में उपयोग कर रहे हैं
यारिन

मुझे लगता है कि यदि आप अपनी फ़ाइलों को अलग करना चाहते हैं, तो - उपयोग करना चाहते हैं, जब आप करते हैं, तो अपनी कॉल साइटों को नामांकित करें, Admin::AdminService.some_actionलेकिन अन्य क्लाइंट साइड एप्लिकेशन जैसे Ember ऐप आपके द्वारा कोड से संबंधित मार्गों का उपयोग करने पर अपने मार्गों को बदलने की आवश्यकता नहीं है अलग करना चाहते हैं। -फुट एक मध्यवर्ती कदम की तरह लगता है जिसे लागू करना आसान हो सकता है।
15:

मैं वर्तमान में एक अंतरराष्ट्रीय एप्लिकेशन पर काम कर रहा हूं, जिसे देश-विशिष्ट नियमों को संभालने की आवश्यकता है, लेकिन फिर भी दुनिया के लिए एक ही इंटरफ़ेस को उजागर करता है। मुझे प्रति देश "कोर" का एक उदाहरण मिला है, एक बार में सभी को संभालने की आवश्यकता नहीं है। "देश के इंजन" का अपने आप कोई मतलब नहीं है, इसलिए "कोर" ऐप के साथ युग्मन एक मुद्दा नहीं है। हालाँकि, मैं उन्हें अपने नामस्थान में नहीं रखना चाहता क्योंकि कोर ऐप को यह नहीं पता होना चाहिए कि वह किस देश में काम कर रहा है। मुझे लगता है कि एक "पूर्ण" इंजन आपकी फ़ाइलों और कक्षाओं को एक मॉड्यूलर तरीके से व्यवस्थित करने की तरह है, लेकिन फिर भी आपके "मोनोलिथ" को जगह में रखता है।
मंकलास

17

मैं वही सोच रहा था और इसलिए, यहाँ समाप्त हुआ। यह मुझे लगता है कि पहले के उत्तर मूल रूप से प्रश्न को कवर करते हैं, लेकिन मुझे लगा कि निम्नलिखित में भी मदद मिल सकती है:

# generate plugins (NOTE: using same name each time to minimize differences)
# -----------------------------------------------------------------------------

$ rails plugin new test-plugin -T
$ mv test-plugin{,.01}

$ rails plugin new test-plugin -T --mountable
$ mv test-plugin{,.02}

$ rails plugin new test-plugin -T --full
$ mv test-plugin{,.03}

$ rails plugin new test-plugin -T --full --mountable
$ mv test-plugin{,.04}




# compare "stock" (01) with "mountable" (02)
# -----------------------------------------------------------------------------

$ diff -r test-plugin.01 test-plugin.02

Only in test-plugin.02: app
Only in test-plugin.02: config
Only in test-plugin.02/lib/test-plugin: engine.rb
diff -r test-plugin.01/lib/test-plugin.rb test-plugin.02/lib/test-plugin.rb
0a1,2
> require "test-plugin/engine"
> 
Only in test-plugin.02: script
diff -r test-plugin.01/test-plugin.gemspec test-plugin.02/test-plugin.gemspec
18a19
>   # s.add_dependency "jquery-rails"




# compare "stock" (01) with "full" (03)
# -----------------------------------------------------------------------------

$ diff -r test-plugin.01 test-plugin.03
Only in test-plugin.03: app
Only in test-plugin.03: config
Only in test-plugin.03/lib/test-plugin: engine.rb
diff -r test-plugin.01/lib/test-plugin.rb test-plugin.03/lib/test-plugin.rb
0a1,2
> require "test-plugin/engine"
> 
Only in test-plugin.03: script
diff -r test-plugin.01/test-plugin.gemspec test-plugin.03/test-plugin.gemspec
18a19
>   # s.add_dependency "jquery-rails"




# compare "mountable" (02) with "full" (03)
# -----------------------------------------------------------------------------

$ diff -r test-plugin.02 test-plugin.03

Only in test-plugin.03/app/assets/javascripts/test-plugin: .gitkeep
Only in test-plugin.02/app/assets/javascripts/test-plugin: application.js
Only in test-plugin.03/app/assets/stylesheets/test-plugin: .gitkeep
Only in test-plugin.02/app/assets/stylesheets/test-plugin: application.css
Only in test-plugin.03/app/controllers: .gitkeep
Only in test-plugin.02/app/controllers: test-plugin
Only in test-plugin.03/app/helpers: .gitkeep
Only in test-plugin.02/app/helpers: test-plugin
Only in test-plugin.03/app/mailers: .gitkeep
Only in test-plugin.03/app/models: .gitkeep
Only in test-plugin.03/app/views: .gitkeep
Only in test-plugin.02/app/views: layouts
diff -r test-plugin.02/config/routes.rb test-plugin.03/config/routes.rb
1c1
< TestPlugin::Engine.routes.draw do
---
> Rails.application.routes.draw do
diff -r test-plugin.02/lib/test-plugin/engine.rb test-plugin.03/lib/test-plugin/engine.rb
3d2
<     isolate_namespace TestPlugin




# compare "mountable" (02) with "full & mountable" (04)
# -----------------------------------------------------------------------------

$ diff -r test-plugin.02 test-plugin.04

<no difference>




# compare "full" (03) with "full & mountable" (04)
# -----------------------------------------------------------------------------

$ diff -r test-plugin.03 test-plugin.04

Only in test-plugin.03/app/assets/javascripts/test-plugin: .gitkeep
Only in test-plugin.04/app/assets/javascripts/test-plugin: application.js
Only in test-plugin.03/app/assets/stylesheets/test-plugin: .gitkeep
Only in test-plugin.04/app/assets/stylesheets/test-plugin: application.css
Only in test-plugin.03/app/controllers: .gitkeep
Only in test-plugin.04/app/controllers: test-plugin
Only in test-plugin.03/app/helpers: .gitkeep
Only in test-plugin.04/app/helpers: test-plugin
Only in test-plugin.03/app/mailers: .gitkeep
Only in test-plugin.03/app/models: .gitkeep
Only in test-plugin.03/app/views: .gitkeep
Only in test-plugin.04/app/views: layouts
diff -r test-plugin.03/config/routes.rb test-plugin.04/config/routes.rb
1c1
< Rails.application.routes.draw do
---
> TestPlugin::Engine.routes.draw do
diff -r test-plugin.03/lib/test-plugin/engine.rb test-plugin.04/lib/test-plugin/engine.rb
2a3
>     isolate_namespace TestPlugin

विशेष रुचि (मेरे लिए) यह तथ्य है कि कोई अंतर नहीं है

rails plugin new test-plugin -T --mountable

तथा

rails plugin new test-plugin -T --full --mountable

शायद इसलिए कि --fullपहले से अधिक है --mountable?
मनकलास

8

अंतर के बारे में मेरी समझ यह है कि इंजन प्लगइन्स की तरह हैं, और मौजूदा अनुप्रयोगों में कार्यक्षमता जोड़ते हैं। जबकि माउंटेबल ऐप्स अनिवार्य रूप से एक एप्लिकेशन हैं, और अकेले खड़े हो सकते हैं।

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


2

मेरा मानना ​​है कि, एक माउंटेबल ऐप होस्ट ऐप से अलग-थलग है, इसलिए वे कक्षाएं - मॉडल, सहायक आदि साझा नहीं कर सकते। ऐसा इसलिए है क्योंकि एक माउंटेबल ऐप एक रैक एंडपॉइंट है (यानी अपने आप में एक रैक ऐप है) )।

डिस्क्लेमर: मेरे पास सबसे अधिक है, केवल रेलिंग 3.1 के साथ शुरू हुआ।


माना। एक बात जो अजीब लगती है, वह यह है कि डिफ़ॉल्ट रूप से, एक इंजन आपको "मॉडल" फ़ोल्डर देता है, लेकिन एक माउंटेबल ऐप नहीं है। मुझे आश्चर्य है कि अगर "सबसे अच्छा अभ्यास" जनरेटर के लिए होगा जिसमें शामिल ऐप के लिए मॉडल बनाते हैं, क्योंकि ऐसा लगता है कि आप इंजन में कोई माइग्रेशन नहीं करना चाहेंगे / moutable
जेरेमी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.