121 votes

Rails 3.1 : Moteur vs. application montable

Quelqu'un peut-il m'aider à comprendre les différences entre un moteur Rails et une application Mountable ? Dans Rails 3.1, vous pouvez créer l'un ou l'autre avec le plugin "rails new". _ __ commande ".

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

Quand souhaitez-vous utiliser l'un ou l'autre ? Je sais qu'il est possible d'empaqueter un Engine en tant que gemme, par exemple. N'est-ce pas le cas pour les Mountable Apps ? Quelles sont les autres différences ?

145voto

astjohn Points 1867

J'ai constaté ce qui suit :

Moteur complet

Avec un moteur complet, l'application mère hérite des routes du moteur. Il n'est pas nécessaire de spécifier quoi que ce soit dans parent_app/config/routes.rb . Il suffit de spécifier la gem dans le fichier Gemfile pour que l'application parente hérite des modèles, des routes, etc. Les routes du moteur sont spécifiées comme suit :

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

Pas d'espacement des noms des modèles, des contrôleurs, etc. Ceux-ci sont immédiatement immédiatement accessibles à l'application mère.

Moteur montable

L'espace de noms du moteur est isolé par défaut :

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

Avec un moteur montable, les routes sont nommées et l'application mère peut regrouper cette fonctionnalité sous une seule route :

# 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 

Les modèles, les contrôleurs, etc. sont isolés de l'application mère - bien que les aides puissent être facilement partagées.

Voici les principales différences que j'ai relevées. Peut-être y en a-t-il d'autres ? J'ai demandé à plus de aquí mais n'a pas encore reçu de réponse.

J'ai l'impression que puisqu'un moteur complet ne s'isole pas de l'application mère, il est préférable de l'utiliser en tant qu'application autonome adjacente à l'application mère. Je pense que des conflits de noms pourraient se produire.

Un moteur montable peut être utilisé dans les situations où vous souhaitez éviter les conflits de noms et regrouper le moteur sous une route spécifique dans l'application mère. Par exemple, je travaille à la construction de mon premier moteur conçu pour le service à la clientèle. L'application mère pourrait regrouper ses fonctionnalités sous une seule route, par exemple :

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

Si mes hypothèses sont erronées, que quelqu'un me le fasse savoir et je corrigerai cette réponse. J'ai rédigé un petit article sur le sujet aquí .

43voto

Yarin Points 18186

Les deux options de générer un moteur. La différence est que, --mountable permettra de créer le moteur isolé de l'espace de noms, alors que --full permettra de créer un moteur qui partage l'espace de noms de l'application principale.

Les différences se manifeste en 3 façons:

1) Le moteur de fichier de classe appellera isolate_namespace:

lib/my_full_engine/moteur.rb:

module MyFullEngine
  class Engine < Rails::Engine
  end
end

lib/my_mountable_engine/moteur.rb:

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

2) Le moteur de l' config/routes.rb fichier sera préfixée:

Moteur:

Rails.application.routes.draw do
end

Monté sur le moteur:

MyMountableEngine::Engine.routes.draw do
end

3) La structure du fichier pour les contrôleurs, les aides, les points de vue, actif et être préfixée:

créer app/controllers/my_mountable_engine/application_controller.rb
créer app/helpers/my_mountable_engine/application_helper.rb
créer app/expéditeurs créer app/models
créer app/views/layouts/my_mountable_engine/de l'application.html.erb
créer app/assets/images/my_mountable_engine
créer app/assets/css/my_mountable_engine/de l'application.css
créer app/assets/javascripts/my_mountable_engine/application.js
créer le fichier config/routes.rb créer lib/my_mountable_engine.rb
créer lib/tasks/my_mountable_engine.râteau
créer lib/my_mountable_engine/version.rb
créer lib/my_mountable_engine/moteur.rb


Explication

Le cas d'utilisation de l' --full option semble être très limitée. Personnellement, je ne peux pas penser à une bonne raison pour laquelle vous souhaitez séparer votre code dans un moteur, sans isoler l'espace de bien - Il aurait essentiellement pour vous donner juste deux étroitement couplé applications de partage à l'identique des structures de fichiers et de tous les conflits et le code de fuite que cela implique.

Chaque pièce de la documentation que j'ai vu montre l' --mountable option, et en effet le courant de bord guide vous encourage fortement à inclure isolate namespace- ce qui est la même chose que de dire utiliser --mountable sur --full.

Enfin, il ya la confusion de la terminologie: Malheureusement, rails plugin -h montre les descriptions suivantes:

[plein] # Générer un moteur rails accompagnée d'une application Rails pour les tests
[--montable] # Générer montage isolé de l'application

Cela donne l'impression que vous utilisez --full de créer un "moteur" et --mountable créer quelque chose d'autre, appelé "montage sur demande", quand en fait ils sont tous les deux moteurs - un espace de noms et un pas. C'est lié à conduire à la confusion que les utilisateurs qui cherchent à créer un moteur sera probablement supposer qu' --full est la plus pertinente option.

Conclusion

  • rails plugin new something --full = Moteur dans votre application espace de noms. (Pourquoi?)
  • rails plugin new something --mountable = Moteur avec son propre espace de noms. (Génial)

Références

17voto

Corey Innis Points 414

Je me posais la même question et j'ai donc atterri ici. Il me semble que les réponses précédentes couvrent essentiellement la question, mais j'ai pensé que ce qui suit pourrait également être utile :

# 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

Ce qui m'intéresse particulièrement, c'est le fait qu'il n'y a pas de différence entre les

rails plugin new test-plugin -T --mountable

y

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

9voto

JDutil Points 2501

Si je comprends bien la différence, les moteurs sont comme des plugins et ajoutent des fonctionnalités à des applications existantes. Les applications montables, quant à elles, sont essentiellement des applications et peuvent être autonomes.

Ainsi, si vous voulez pouvoir l'exécuter seule ou dans une autre application, vous devez créer une application montable. Si vous souhaitez qu'il soit ajouté à des applications existantes, mais qu'il ne fonctionne pas seul, vous en ferez un moteur.

2voto

Kris Points 3781

La différence, je crois, est que les applications montables sont isolées de l'application hôte, et ne peuvent donc pas partager de classes - modèles, aides, etc. C'est parce qu'une application montable est un point de terminaison Rack (c'est-à-dire une application Rack à part entière).

Avertissement : comme la plupart des gens, je commence tout juste à jouer avec Rails 3.1.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X