it-swarm.com.ru

Rails 3.1: Engine против монтируемого приложения

Может кто-нибудь помочь мне понять разницу между движком Rails и ​​подключаемым приложением? В Rails 3.1 вы можете создать любой из них с помощью команды "Новый плагин Rails _ __" ,.

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

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

119
Jeremy Raines

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

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

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

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

140
astjohn

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

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

1) Файл класса движка будет вызывать isolate_namespace:

Библиотека/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) Файл 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
создать приложение/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, и, действительно, текущий Руководство по Edge настоятельно рекомендует вам включить isolate namespace-, что аналогично тому, как использовать --mountable over --full.

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

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

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

Заключение

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

Рекомендации

38
Yarin

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

# 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
17
Corey Innis

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

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

8
JDutil

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

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

2
Kris