Rails 3.1: Engine против монтируемого приложения - PullRequest
119 голосов
/ 25 мая 2011

Может кто-нибудь помочь мне понять разницу между Rails Engine и Mountable приложением?В Rails 3.1 вы можете создать любой из них с помощью команды «rails new plugin _ __ ».

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

Когда вы хотите использовать один изДругой?Я знаю, что вы можете упаковать двигатель как драгоценный камень, например.Разве это не относится к монтируемым приложениям?Какие еще различия есть?

Ответы [ 5 ]

140 голосов
/ 26 июля 2011

Я заметил следующее:

Полный двигатель

При полном двигателе родительское приложение наследует маршруты от двигателя.Нет необходимости указывать что-либо в parent_app/config/routes.rb.Указание гема в Gemfile достаточно для того, чтобы родительское приложение унаследовало модели, маршруты и т. Д. Маршруты движка указываются следующим образом:

# 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" 

Если я ошибаюсь в своих предположениях, кто-то, пожалуйста, сообщите мне, и я исправлю этот ответ.Я сделал небольшую статью на эту тему здесь Ура!

38 голосов
/ 23 июня 2013

Обе опции генерируют двигатель .Разница в том, что --mountable создаст движок в изолированном пространстве имен, тогда как --full создаст движок, который разделяет пространство имен основного приложения.

Различия будут проявляться тремя способами:

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
создать приложение / helpers / my_mountable_engine / application_helper.rb
создать приложение / почтовые программы создать приложение / модели
создать приложение / views / layouts / my_mountable_engine / application.html.erb
crесть приложение / assets / images / my_mountable_engine
создать приложение / assets / stylesheets / my_mountable_engine / application.css
создать приложение / assets / javascripts / my_mountable_engine / application.js
создать config / rout.rb создать lib / my_mountable_engine.rb
создать lib / tasks / my_mountable_engine.rake
создать lib / my_mountable_engine / version.rb
создать lib / my_mountable_engine/engine.rb


Пояснение

Вариант использования опции --full представляется очень ограниченным.Лично я не могу придумать ни одной веской причины, по которой вы захотите разделить ваш код на движок без изоляции пространства имен. По сути, это просто даст вам два тесно связанных приложения, использующих идентичные файловые структуры и все конфликты и утечку кода.это влечет за собой.

Каждая часть документации, которую я видел, демонстрирует опцию --mountable, и, действительно, текущее руководство по краям настоятельно рекомендует вам включить isolate namespace - то же самое, что сказать "использование" --mountable over --full.

Наконец, возникла путаница с терминологией: К сожалению, rails plugin -h показывает следующие описания:

[- full] # Создать rails engine с приложением Rails для тестирования
[--mountable] # Создать монтируемое изолированное приложение

Создается впечатление, что вы используете --full для создания «движка» и --mountableсоздать что-то еще, называемое «монтируемое приложение», когда на самом деле они оба движка - одно пространство имен, а другое нет.Это может привести к путанице, поскольку пользователи, желающие создать движок, скорее всего, предположят, что --full является более подходящим вариантом.

Заключение

  • rails plugin new something --full = Двигатель в вашем приложенииПространство имен.(С чего бы это?)
  • rails plugin new something --mountable = Двигатель со своим собственным пространством имен.(Великолепно)

Ссылки

17 голосов
/ 25 сентября 2012

Мне было то же самое, и поэтому я оказался здесь.мне кажется, что более ранние ответы в основном охватывают вопрос, но я подумал, что следующее также может помочь:

# 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
8 голосов
/ 09 июля 2011

Мое понимание разницы заключается в том, что движки похожи на плагины и добавляют функциональность существующим приложениям. В то время как монтируемые приложения, по сути, являются приложениями, и могут быть автономными.

Так что, если вы хотите иметь возможность запускать его самостоятельно или в другом приложении, вы можете создать монтируемое приложение. Если вы собираетесь добавить его в существующие приложения, но не запускать сами по себе, вы сделаете его движком.

2 голосов
/ 02 июня 2011

Разница, на мой взгляд, в том, что монтируемые приложения изолированы от хост-приложения, поэтому они не могут делиться классами - моделями, помощниками и т. Д. Это потому, что монтируемое приложение является конечной точкой Rack (т.е. свое право).

Отказ от ответственности: я, как и большинство, только начал играть с Rails 3.1.

...