Rails 3.1: Motor ve Monte Edilebilir Uygulama Karşılaştırması


120

Birisi bir Rails Engine ile bir Monte Edilebilir uygulama arasındaki farkları anlamama yardımcı olabilir mi? Rails 3.1'de, "rails new plugin _ __ " komutuyla ikisinden birini oluşturabilirsiniz .

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

Ne zaman birini diğerine karşı kullanmak istersiniz? Bir tane için bir Motoru bir mücevher olarak paketleyebileceğinizi biliyorum. Monte Edilebilir Uygulamalar için durum böyle değil mi? Başka ne gibi farklılıklar var?

Yanıtlar:


143

Aşağıdakileri fark ettim:

Tam Motor

Tam motorla üst uygulama, rotaları motordan devralır. İçinde herhangi bir şey belirtmek gerekli değildir parent_app/config/routes.rb. Gemfile'da gem'i belirtmek, üst uygulamanın modelleri, rotaları vb. Devralması için yeterlidir. Motor rotaları şu şekilde belirtilir:

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

Modellerin, denetleyicilerin vb. Ad aralığı yoktur. Bunlara ana uygulama tarafından hemen erişilebilir.

Monte Edilebilir Motor

Motorun ad alanı varsayılan olarak yalıtılmıştır:

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

Monte edilebilir bir motorla, rotalar ad alanlıdır ve ana uygulama bu işlevi tek bir yol altında paketleyebilir:

# 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 

Modeller, kontrolörler vb. Ana uygulamadan izole edilmiştir - ancak yardımcılar kolayca paylaşılabilir.

Bunlar, gördüğüm ana farklılıklar. Belki başkaları da vardır? Ben üzerinden istediler burada , ama bir yanıt almayı henüz.

Benim izlenimime göre, tam bir motor kendisini ana uygulamadan izole etmediğinden, en iyi şekilde ana uygulamaya bitişik bağımsız bir uygulama olarak kullanılır. İsim çatışmalarının olabileceğine inanıyorum.

Ad çakışmalarını önlemek ve motoru ana uygulamadaki belirli bir yol altında toplamak istediğiniz durumlarda monte edilebilir bir motor kullanılabilir. Örneğin, müşteri hizmetleri için tasarlanmış ilk motorumu oluşturmak için çalışıyorum. Ana uygulama, işlevlerini aşağıdaki gibi tek bir yol altında toplayabilir:

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

Varsayımlarımdan çok uzaksam, lütfen birisi bana haber versin, bu yanıtı düzeltirim. Konuyla ilgili burada küçük bir yazı yazdım Şerefe!


1
Monte edilebilir bir motor, ana uygulamanın köküne yönlendirilebilir / monte edilebilir mi?
Slick23

3
@JustinM deneyebilirsin mount MyEngine::Engine => "/". Kaynaklar için çalışıyor, belki motorlar için de durum böyledir.
Benoit Garret

2
@astjohn Bloglarınızın harika bir özeti. Ama tersi olmaz mıydı? Bir Tam Motor "eksik" olur ve üst uygulamanın çalışması gerekirken, Monte Edilebilir Motor ana uygulamadan "izole" olduğu için bağımsız olarak çalışabilir mi?
Theo Scholiadis

39

Her iki seçenek de bir motor oluşturacaktır . Aradaki fark, --mountablemotoru izole edilmiş bir ad --fullalanında oluştururken, ana uygulamanın ad alanını paylaşan bir motor oluşturacak olmasıdır.

Farklılıklar 3 şekilde ortaya çıkacaktır:

1) Motor sınıfı dosyası şunları arayacaktır 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) Motorun config/routes.rbdosyası isim alanlı olacaktır:

Tam motor:

Rails.application.routes.draw do
end

Takılı motor:

MyMountableEngine::Engine.routes.draw do
end

3) Denetleyiciler, yardımcılar, görünümler ve varlıklar için dosya yapısı ad alanlı olacaktır:

uygulama oluştur / denetleyiciler / my_mountable_engine /application_controller.rb
uygulama oluştur / yardımcılar / my_mountable_engine /application_helper.rb
uygulama oluştur / postacılar uygulama oluştur / modeller
uygulama oluştur / görünümler / düzenler / my_mountable_engine /application.html.erb
uygulama / varlıklar / resimler / my_mountable_engine oluştur
uygulama / varlıklar / stil sayfaları / my_mountable_engine /application.css
oluştur uygulama / varlıklar / javascripts / my_mountable_engine /application.js
oluştur config / route.rb lib / my_mountable_engine.rb
oluştur lib / görevler / my_mountable_engine.rake
lib / my_mountable_engine oluştur .rb
lib / my_mountable_engine / engine.rb oluştur


açıklama

--fullSeçenek için kullanım durumu çok sınırlı görünüyor. Şahsen, kodunuzu ad alanını da izole etmeden bir motora ayırmak isteyeceğinizin iyi bir nedenini düşünemiyorum - Esasen, size aynı dosya yapılarını ve tüm çakışmaları ve kod sızıntısını paylaşan iki sıkı bağlanmış uygulama verecektir. bu gerektirir.

Gördüğüm her belge parçası --mountableseçeneği gösteriyor ve gerçekten de mevcut kenar kılavuzu sizi dahil etmeye şiddetle teşvik ediyor isolate namespace- bu, --mountablebitti demekle aynı şey --full.

Sonunda terminoloji karışıklığı var: Maalesef rails plugin -haşağıdaki açıklamaları gösteriyor:

[--full] # Test için paketlenmiş Rails uygulamasıyla bir ray motoru oluşturun
[--mountable] # Monte edilebilir yalıtılmış uygulama oluşturun

Bu, --fullbir "motor" --mountableoluşturmak ve "monte edilebilir uygulama" adı verilen başka bir şey yaratmak için kullandığınız izlenimini verir; aslında ikisi de motorlar - biri ad alanlı ve biri değil. Bir motor oluşturmak isteyen kullanıcılar muhtemelen --fullbunun daha alakalı seçenek olduğunu varsayacaklarından, bu kafa karışıklığına yol açacaktır .

Sonuç

  • rails plugin new something --full= Uygulamanızın ad alanındaki motor. (Neden yapasın?)
  • rails plugin new something --mountable= Kendi ad alanına sahip motor. (Korku)

Referanslar


9
Kullanmak için iyi bir neden --fullvar: Eğer bir raylar web sitesinin parçalarına sahipseniz, entegre olmasını (izole edilmiş bir ad alanında değil) ve yine de farklı ray projeleri arasında paylaşmak isteyebilirsiniz. Ayrıca bundan daha basit olabilir: belki de cevheriniz o kadar eklemeyebilir, ancak onu doğru bir şekilde takabilmek istiyorsunuz.
nathanvda

2
@nathanvda - Doğru, ama bence birden fazla projede bir şey paylaşıyorsanız, gerçekten isim alanlı olmalıdır , çünkü temelde eklenti olarak kullanıyorsunuz
Yarin

Sanırım dosyalarınızı izole etmek istiyorsanız, arama sitelerinizi ad alanını kullanmak isteyebilirsiniz, Admin::AdminService.some_actionancak Ember uygulaması gibi diğer istemci tarafı uygulamaları sizin kodunuzla ilgili yolları kullanırsa rotalarınızı değiştirmek zorunda kalmazsınız. izole etmek istiyorum. --full, uygulaması daha kolay olabilecek bir ara adım gibi görünüyor.
Jwan622

Şu anda, ülkeye özgü düzenlemeleri ele alması gereken, ancak yine de aynı arayüzü dünyaya sunan uluslararası bir uygulama üzerinde çalışıyorum. Ülke başına bir "Çekirdek" örneğim var, hepsini birden halletmeye gerek yok. "Ülke motorları" kendi başlarına bir anlam ifade etmiyor, bu nedenle "temel" uygulama ile bağlantı sorun değil. Ancak, çekirdek uygulamanın hangi ülkede çalıştığını bilmemesi gerektiğinden kendi ad alanlarında olmalarını istemiyorum. "Tam" bir motorun daha çok dosyalarınızı ve sınıflarınızı modüler bir şekilde organize etmeye benzediğini, ancak "tek parçanızı" yerinde tutmaya devam ettiğini düşünüyorum.
Mankalas

17

Ben de aynı şeyi merak ediyordum ve bu yüzden burada sona erdi. Bana öyle geliyor ki önceki cevaplar temelde soruyu kapsıyor, ancak aşağıdakilerin de yardımcı olabileceğini düşündüm:

# 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

(benim için) özellikle ilgi çekici olan şey, aralarında hiçbir fark olmamasıdır.

rails plugin new test-plugin -T --mountable

ve

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

Belki --fullde önceliğin bittiği içindir --mountable?
Mankalas

8

Farkı anladığım kadarıyla motorlar eklentilere benziyor ve mevcut uygulamalara işlevsellik katıyor. Monte edilebilir uygulamalar esasen bir uygulamadır ve tek başına durabilir.

Dolayısıyla, onu kendi başına veya başka bir uygulama içinde çalıştırabilmek istiyorsanız, monte edilebilir bir uygulama yaparsınız. Mevcut uygulamalara bir ek olmasını amaçlıyorsanız, ancak kendi başına çalıştırılmıyorsa, onu bir motor yaparsınız.


2

Sanırım fark, monte edilebilir bir uygulamanın ana uygulamadan izole edilmiş olmasıdır, bu nedenle sınıfları paylaşamazlar - modeller, yardımcılar vs. ).

Feragatname: Çoğu kişi gibi ben de sadece Rails 3.1 ile oynamaya başladım.


Kabul. Garip görünen bir şey de, varsayılan olarak bir Motorun size bir "modeller" klasörü vermesidir, ancak bir Monte Edilebilir Uygulamanın vermemesidir. Motorda / moutable'da herhangi bir geçiş yapmak istemeyeceğinizden "en iyi uygulama", dahil edilen uygulama için modeller oluşturan jeneratörlere sahip olmak mı acaba?
Jeremy Raines
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.