ruby on rails 3 - from - Rails 3.1: Aplicación Engine vs. Mountable
rails render partial from controller (5)
¿Alguien puede ayudarme a entender las diferencias entre un motor Rails y una aplicación montable? En Rails 3.1, puede crear cualquiera con el comando "rails new plugin _ __ ".
rails plugin new forum --full # Engine
rails plugin new forum --mountable # Mountable App
¿Cuándo querrías usar uno versus el otro? Sé que puedes empaquetar un motor como una gema, por ejemplo. ¿No es ese el caso de las aplicaciones montables? ¿Qué otras diferencias hay?
Ambas opciones generarán un engine . La diferencia es que --mountable
creará el motor en un espacio de nombre aislado, mientras que --full
creará un motor que comparte el espacio de nombre de la aplicación principal.
Las diferencias se manifestarán de 3 maneras:
1) El archivo de clase de motor llamará 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) El archivo config/routes.rb
del motor será namespaced:
Motor completo:
Rails.application.routes.draw do
end
Motor montado:
MyMountableEngine::Engine.routes.draw do
end
3) La estructura de archivos para los controladores, los ayudantes, las vistas y los activos serán espacios de nombres:
crear aplicaciones / controladores / my_mountable_engine /application_controller.rb
crear la aplicación / helpers / my_mountable_engine /application_helper.rb
crear aplicaciones / publicistas crear aplicaciones / modelos
crear aplicaciones / vistas / diseños / my_mountable_engine /application.html.erb
crear aplicación / assets / images / my_mountable_engine
crear aplicación / assets / stylesheets / my_mountable_engine /application.css
crear aplicación / assets / javascripts / my_mountable_engine /application.js
crear config / routes.rb create lib / my_mountable_engine.rb
crear lib / tasks / my_mountable_engine.rake
crear lib / my_mountable_engine / version.rb
crear lib / my_mountable_engine / engine.rb
Explicación
El caso de uso para la opción --full
parece ser muy limitado. Personalmente, no puedo pensar en ninguna buena razón por la que quieras separar tu código en un motor sin aislar el espacio de nombres. En esencia, solo te daría dos aplicaciones estrechamente acopladas que comparten estructuras de archivos idénticas y todos los conflictos y fugas de código. eso implica.
Cada pieza de documentación que he visto demuestra la opción --mountable
, y de hecho, la guía de borde actual lo alienta encarecidamente a que incluya el isolate namespace
, que es lo mismo que decir uso, que se puede --mountable
través de --full
.
Finalmente, hay una confusión terminológica: desafortunadamente, el rails plugin -h
muestra las siguientes descripciones:
[--full] # Genera un motor de rieles con la aplicación Rails incluida para pruebas
[--moyableble] # Generar aplicación aislada montable
Esto da la impresión de que utiliza --full
para crear un "motor" y - --mountable
de crear algo más llamado "aplicación montable", cuando de hecho son ambos motores, uno de espacio de nombres y otro no. Eso seguramente generará confusión ya que los usuarios que buscan crear un motor probablemente suponen que --full
es la opción más relevante.
Conclusión
-
rails plugin new something --full
= Engine en el espacio de nombres de su aplicación. (¿Por que lo harias?) -
rails plugin new something --mountable
= Engine con su propio espacio de nombres. (Increíble)
Referencias
He notado lo siguiente:
Motor completo
Con un motor completo, la aplicación principal hereda las rutas del motor. No es necesario especificar nada en parent_app/config/routes.rb
. Especificar la gema en Gemfile es suficiente para que la aplicación padre herede los modelos, rutas, etc. Las rutas del motor se especifican como:
# my_engine/config/routes.rb
Rails.application.routes.draw do
# whatever
end
Sin espacios de nombres de modelos, controladores, etc. Estos son accesibles inmediatamente para la aplicación principal.
Motor montable
El espacio de nombre del motor está aislado de manera predeterminada:
# my_engine/lib/my_engine/engine.rb
module MyEngine
class Engine < Rails::Engine
isolate_namespace MyEngine
end
end
Con un motor que se puede montar, las rutas tienen un espacio de nombres y la aplicación principal puede agrupar esta funcionalidad en una única ruta:
# 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
Los modelos, controladores, etc. están aislados de la aplicación principal, aunque los ayudantes se pueden compartir fácilmente.
Estas son las principales diferencias que he visto. Quizás hay otros? He preguntado por here , pero todavía no he recibido una respuesta.
Mi impresión es que, dado que un motor completo no se aísla de la aplicación principal, es mejor utilizarlo como una aplicación independiente junto a la aplicación principal. Creo que los enfrentamientos de nombres podrían ocurrir.
Se podría usar un motor montable en situaciones en las que desee evitar conflictos de nombres y agrupar el motor bajo una ruta específica en la aplicación principal. Por ejemplo, estoy trabajando en la construcción de mi primer motor diseñado para el servicio al cliente. La aplicación principal podría agrupar su funcionalidad en una sola ruta como, por ejemplo:
mount Cornerstone::Engine => "/cornerstone", :as => "help"
Si estoy muy equivocado en mis suposiciones, alguien hágamelo saber y corregiré esta respuesta. He hecho un pequeño artículo sobre el tema here ¡Salud!
La diferencia, creo, es que las aplicaciones montables están aisladas de la aplicación host, por lo que no pueden compartir clases: modelos, ayudantes, etc. Esto se debe a que una aplicación montable es un punto final Rack (es decir, una aplicación Rack por derecho propio )
Descargo de responsabilidad: Yo, como la mayoría, solo he empezado a jugar con Rails 3.1.
Me preguntaba lo mismo y, por lo tanto, terminé aquí. me parece que las respuestas anteriores básicamente cubren la pregunta, pero pensé que lo siguiente también podría ayudar:
# 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
de particular interés (para mí) es el hecho de que no hay diferencia entre
rails plugin new test-plugin -T --mountable
y
rails plugin new test-plugin -T --full --mountable
Mi comprensión de la diferencia es que los motores son como complementos y agregan funcionalidad a las aplicaciones existentes. Mientras que las aplicaciones montables son esencialmente una aplicación, y pueden ser independientes.
Entonces, si quieres poder ejecutarlo solo o dentro de otra aplicación, harías una aplicación de montaje. Si tiene la intención de que sea una adición a las aplicaciones existentes, pero no se ejecute por sí mismo, lo convertiría en un motor.