Rails 3.1: silnik a aplikacja do montażu

Czy ktoś może mi pomóc zrozumieć różnice między silnikiem Rails a aplikacją do montażu? W Rails 3.1 możesz utworzyć jedną z nich za pomocą "rails new plugin ___" dowództwo.

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

Kiedy chcesz użyć jednego kontra drugiego? Wiem, że możesz zapakować silnik jako klejnot. Czy tak nie jest w przypadku aplikacji do montażu? Jakie są inne różnice?

Author: Jeremy Raines, 2011-05-25

5 answers

Zauważyłem:

Pełny Silnik

Przy pełnym silniku aplikacja nadrzędna dziedziczy trasy z silnika. Nie jest konieczne określanie czegokolwiek w parent_app/config/routes.rb. Podanie gem w Gemfile wystarczy, aby aplikacja nadrzędna dziedziczyła modele, trasy itp. Trasy silnika są określone jako:

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

Brak przestrzeni nazw modeli, kontrolerów itp. Są to dostępne dla aplikacji nadrzędnej.

Możliwość montażu Silnik

Przestrzeń nazw silnika jest domyślnie izolowana:

# my_engine/lib/my_engine/engine.rb
module MyEngine 
  class Engine < Rails::Engine 
    isolate_namespace MyEngine 
  end 
end
Dzięki silnikowi do montażu trasy są przestrzenią nazw, a aplikacja nadrzędna może połączyć tę funkcję w jedną trasę:
# 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 

Modele, Kontrolery itp. są odizolowane od aplikacji nadrzędnej - chociaż helpery można łatwo udostępniać.

To są główne różnice, które zauważyłem. Może są inni? Pytałem o tutaj , ale nie otrzymałem jeszcze odpowiedź.

Mam wrażenie, że ponieważ pełny silnik nie izoluje się od aplikacji macierzystej, najlepiej jest go używać jako samodzielnej aplikacji sąsiadującej z aplikacją macierzystą. Wierzę, że mogą wystąpić starcia.

Silnik z możliwością montażu może być używany w sytuacjach, w których chcesz uniknąć konfliktów nazw i połączyć silnik pod jedną konkretną trasą w aplikacji nadrzędnej. Na przykład pracuję nad zbudowaniem mojego pierwszego silnika przeznaczonego do obsługi klienta. Rodzic aplikacja może łączyć swoją funkcjonalność pod jedną trasą, taką jak:

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

Jeśli jestem daleko w moich założeniach, ktoś proszę dać mi znać, a ja naprawię tę odpowiedź. Zrobiłem mały artykuł na ten temat tutaj na zdrowie!

 139
Author: astjohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-18 21:04:50

Obie opcje wygenerują silnik . Różnica polega na tym, że --mountable utworzy silnik w izolowanej przestrzeni nazw, podczas gdy --full utworzy silnik, który dzieli przestrzeń nazw głównej aplikacji.

Różnice przejawiać się będą na 3 sposoby:

1) plik klasy silnika wywoła 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) Na plik config/routes.rb silnika zostanie umieszczony w przestrzeni nazw:

Pełny silnik:

Rails.application.routes.draw do
end

Zamontowany silnik:

MyMountableEngine::Engine.routes.draw do
end

3) struktura plików dla kontrolerów, helperów, widoków i zasobów będzie miała przestrzeń nazw:

Utwórz aplikację / Kontrolery / my_mountable_engine/application_controller.rb
tworzenie aplikacji / helpers / my_mountable_engine / application_helper.rb
tworzenie aplikacji / mailerów tworzenie aplikacji / modeli
Utwórz app/views/layouts / my_mountable_engine / application.html.erb
tworzenie aplikacji / aktywów / obrazy / my_mountable_engine
tworzenie aplikacji / zasobów / arkuszy stylów / my_mountable_engine /Aplikacja.css
create app/assets/javascripts/my_mountable_engine / application.js
Utwórz Config / routes.RB create lib / my_mountable_engine.rb
Utwórz lib / tasks / my_mountable_engine.grabie
Utwórz lib / my_mountable_engine / version.rb
Utwórz lib / my_mountable_engine / engine.rb


Wyjaśnienie

Przypadek użycia opcji --full wydaje się być bardzo ograniczony. Osobiście nie mogę wymyślić żadnego dobrego powodu, dla którego chciałbyś oddzielić swój kod w silnik bez izolowania przestrzeni nazw - w zasadzie dałoby to po prostu dwie ściśle powiązane aplikacje dzielące identyczne struktury plików i wszystkie konflikty i wyciek kodu, które pociągają za sobą.

Każdy kawałek dokumentacji, który widziałem pokazuje opcję --mountable i rzeczywiście obecny przewodnik Edge guide zdecydowanie zachęca do włączenia isolate namespace - co jest tym samym, co użycie --mountable nad --full.

W końcu jest zamieszanie terminologiczne: niestety rails plugin -h pokazuje następujące opisy:

[--full] # Wygeneruj silnik rails z dołączoną aplikacją Rails do testów
[--mountable] # Wygeneruj izolowaną aplikację do montowania

To daje wrażenie, że używasz --full do tworzenia "silnika" i --mountable do tworzenia czegoś innego o nazwie "aplikacja montowalna", podczas gdy w rzeczywistości są to oba silniki - jeden w przestrzeni nazw, a drugi nie. Może to prowadzić do nieporozumień, ponieważ użytkownicy chcący stworzyć silnik prawdopodobnie będą zakładać, że --full jest bardziej odpowiednią opcją.

Podsumowanie

  • rails plugin new something --full = silnik w przestrzeni nazw aplikacji. (Dlaczego?)
  • rails plugin new something --mountable = silnik z własną przestrzenią nazw. (Awesome)

Referencje

 37
Author: Yarin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-23 17:34:42

Zastanawiałam się nad tym samym i dlatego wylądowałam tutaj. wydaje mi się, że wcześniejsze odpowiedzi zasadniczo obejmują pytanie, ale pomyślałem, że następujące mogą również pomóc: {]}

# 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

Szczególnie interesujący (dla mnie) jest fakt, że nie ma różnicy między

rails plugin new test-plugin -T --mountable

I

rails plugin new test-plugin -T --full --mountable
 16
Author: Corey Innis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-25 08:02:57

Rozumiem różnicę, że silniki są jak wtyczki i dodają funkcjonalność do istniejących aplikacji. Podczas gdy aplikacje do montażu są zasadniczo aplikacją i mogą być samodzielne.

Więc jeśli chcesz być w stanie uruchomić go samodzielnie lub w innej aplikacji, można zrobić aplikację montowalną. Jeśli chcesz, aby był on dodatkiem do istniejących aplikacji, ale nie był uruchamiany samodzielnie, uczynisz go silnikiem.

 8
Author: JDutil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-09 08:11:54

Różnica, jak sądzę, jest taka, że aplikacje montowalne są odizolowane od aplikacji hosta, więc nie mogą udostępniać klas-modeli, helperów itp. Dzieje się tak, ponieważ aplikacja do montażu jest punktem końcowym Szafy Rack (tzn. sama aplikacja Rack).

Disclaimer: jak większość, dopiero zacząłem bawić się Rails 3.1.

 2
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-02 10:14:53