Rails 3.1:引擎与可安装的应用程序

| 有人可以帮助我了解Rails Engine和可安装应用之间的区别吗?在Rails 3.1中,您可以使用\“ rails new plugin ___ \”命令创建一个。
rails plugin new forum --full        # Engine
rails plugin new forum --mountable   # Mountable App
您什么时候要使用另一个?我知道您可以将Engine打包为gem。可挂载应用程序不是这种情况吗?还有什么其他区别?     
已邀请:
我注意到以下几点: 全引擎 对于完整的引擎,父应用程序将从引擎继承路由。不需要在
parent_app/config/routes.rb
中指定任何内容。在Gemfile中指定gem足以使父应用程序继承模型,路线等。引擎路线指定为:
# 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\" 
如果我的假设不理想,请告诉我,我将解决此问题。我在这里干了一篇关于这个主题的小文章!     
这两个选项都会生成一个引擎。不同之处在于,“ 6”将在隔离的名称空间中创建引擎,而“ 7”将创建共享主应用程序名称空间的引擎。 差异将通过3种方式体现出来: 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   创建app / helpers / my_mountable_engine / application_helper.rb   创建应用程序/邮件创建应用程序/模型   创建app / views / layouts / my_mountable_engine / application.html.erb   创建应用程序/资产/图像/ my_mountable_engine   创建应用程序/资产/样式表/my_mountable_engine/application.css   创建应用程序/资产/javascript/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
而不是ѭ7the相同。 最后是术语混淆:不幸的是,“ 19”显示了以下描述:   [--full]#使用捆绑的Rails应用程序生成一个Rails引擎进行测试   [--mountable]#生成可安装的隔离应用程序 这给人的印象是,您实际上使用
--full
创建一个“引擎”,并使用ѭ6else创建其他称为“可安装应用程序”的东西,而实际上它们都是引擎-一个命名空间而不是两个。这注定会引起混乱,因为希望创建引擎的用户可能会认为ѭ7是更相关的选项。 结论
rails plugin new something --full
=应用程序名称空间中的引擎。 (为什么?)
rails plugin new something --mountable
=带有其自己的名称空间的引擎。 (真棒) 参考文献 http://edgeguides.rubyonrails.org/engines.html http://api.rubyonrails.org/classes/Rails/Engine.html http://railscasts.com/episodes/277-mountable-engines https://github.com/rails/rails/pull/6499     
我在想同样的事情,因此就到这里了。在我看来,较早的答案基本上涵盖了该问题,但我认为以下内容可能也会有所帮助:
# 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
    
我对差异的理解是,引擎就像插件一样,为现有应用程序添加功能。尽管可挂载应用程序本质上是一个应用程序,并且可以独立运行。 因此,如果您希望能够单独运行它或在另一个应用程序中运行它,则可以制作一个可安装的应用程序。如果您打算将它添加到现有应用程序中,但不单独运行,则可以使其成为引擎。     
我认为,区别在于可安装应用程序与主机应用程序是隔离的,因此它们无法共享类(模型,助手等)。这是因为可安装应用程序是Rack端点(即Rack应用程序)在自己的权利)。 免责声明:与大多数人一样,我只是刚刚开始使用Rails 3.1。     

要回复问题请先登录注册