Rails 3.1: приложение Engine to Mountable

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

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

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

Ответ 1

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

Полный движок

С полным движком родительское приложение наследует маршруты от движка. Нет необходимости указывать что-либо в 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" 

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

Ответ 2

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

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

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

lib/my_full_engine/engine.rb:

module MyFullEngine
  class Engine < Rails::Engine
  end
end

Библиотека /my _mountable_engine/engine.rb:

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

2) Файл engine config/routes.rb будет содержать имена:

Полный движок:

Rails.application.routes.draw do
end

Установленный движок:

MyMountableEngine::Engine.routes.draw do
end

3) Структура файлов для контроллеров, помощников, представлений и активов будет размещена в пространстве имен:

создать приложение/контроллеры/ my_mountable_engine/application_controller.rb
создать приложение/помощники/ my_mountable_engine/application_helper.rb
создать приложение/почтовые программы для создания приложений/моделей
создать приложение /views/layouts/ my_mountable_engine/application.html.erb
создать приложение/активы/изображения/ my_mountable_engine
создать приложение/активы/таблицы стилей / my_mountable_engine/application.css
создать приложение/активы/javascripts/ my_mountable_engine/application.js
создать config/routes.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 над --full.

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

[- full] # Создайте движок рельсов с помощью прилагаемого приложения Rails для тестирования
[--mountable] # Создать монтируемое изолированное приложение

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

Заключение

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

Ссылки

Ответ 3

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

# 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

Ответ 4

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

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

Ответ 5

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

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