Рельсы 3.1: двигатель против монтируемого приложения


может ли кто-нибудь помочь мне понять различия между двигателем Rails и монтируемым приложением? В Rails 3.1 вы можете создать любой из них с помощью "rails new plugin ___ команда".

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

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

5 118

5 ответов:

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

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

С полным движком родительское приложение наследует маршруты от движка. Не надо ничего указывать в parent_app/config/routes.rb. Указание gem в 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" 

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

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

различия будут проявляться в 3 вариантах:

1) файл класса двигателя вызовет isolate_namespace:

lib/my_full_engine / engine.РБ:

module MyFullEngine
  class Engine < Rails::Engine
  end
end

lib/my_mountable_engine / engine.РБ:

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.РБ
создать приложение/помощники/my_mountable_engine / application_helper.РБ
создать приложение / почтовые программы создать приложение / модели
создать приложение/просмотров/макеты/my_mountable_engine/заявления.формат html.Эрб
создать приложение/активы/изображения/my_mountable_engine
создать приложение / активы / таблицы стилей/my_mountable_engine/заявления.css
создать приложение/активов/скрипты/my_mountable_engine/заявления.js
создать файл config/маршруты.rb create lib / my_mountable_engine.РБ
создайте lib/tasks / my_mountable_engine.грабли
создайте lib/my_mountable_engine / version.РБ
создайте lib/my_mountable_engine / engine.РБ


объяснение

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

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

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

[--full] # Generate a рельсы двигатель С приложением bundled Rails для тестирования
[--mountable] # создание монтируемого изолированного приложения

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

вывод

  • rails plugin new something --full = двигатель в пространстве имен вашего приложения. (Зачем тебе это?)
  • rails plugin new something --mountable = двигатель с собственным пространством имен. (Потрясающе)

ссылки

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

# 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

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

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

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

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