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

有人能帮我理解一个Rails引擎和一个Mountable应用程序之间的区别吗? 在Rails 3.1中,您可以使用“rails new plugin _ __ ”命令创build任意一个。

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

你想什么时候用一个呢? 我知道你可以将引擎打包成一个gem。 对于可安装的应用程序,情况不是这样吗? 还有什么其他的区别?

我注意到了以下几点:

完整的引擎

对于完整的引擎,父应用程序将inheritance引擎的路由。 没有必要在parent_app/config/routes.rb指定任何内容。 在Gemfile中指定gem足以让父应用程序inheritance模型,路由等。引擎路由指定为:

 # 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 

使用可挂载的引擎,路由是命名空间的,父应用程序可以在单一路由下捆绑该function:

 # 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 

模型,控制器等与父应用程序隔离 – 尽pipe助手可以轻松共享。

这些是我发现的主要区别。 也许还有别人? 我已经在这里问过了 ,但还没有收到答复。

我的印象是,因为一个完整的引擎不会将自己与父应用程序隔离,所以最好将它用作与父应用程序相邻的独立应用程序。 我相信名称冲突可能发生。

可安装的引擎可用于您希望避免名称冲突的情况,并将引擎捆绑在父应用程序的特定path下。 例如,我正在为构build我的第一个为客户服务而devise的引擎工作。 父应用程序可以将其function绑定在单个路由下,例如:

 mount Cornerstone::Engine => "/cornerstone", :as => "help" 

如果我按照我的假设走了,有人请让我知道,我会解决这个问题。 我在这里做了一个关于这个问题的小文章干杯!

这两个选项都会生成一个引擎 。 不同之处在于--mountable将在独立的命名空间中创build引擎,而--full将创build一个共享主应用程序名称空间的引擎。

差异将体现在三个方面:

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)控制器,助手,视图和资产的文件结构将被命名空间:

创build应用程序/控制器/ my_mountable_engine /application_controller.rb
创buildapp / helpers / my_mountable_engine /application_helper.rb
创build应用程序/邮件创build应用程序/模型
创buildapp / views / layouts / my_mountable_engine /application.html.erb
创build应用程序/资产/图像/ my_mountable_engine
创buildapp / assets / stylesheets / my_mountable_engine /application.css
创buildapp / assets / javascripts / my_mountable_engine /application.js
创buildconfig / routes.rb创buildlib / my_mountable_engine.rb
创buildlib / tasks / my_mountable_engine.rake
创buildlib / my_mountable_engine / version.rb
创buildlib / my_mountable_engine / engine.rb


说明

--full选项的用例似乎非常有限。 就我个人而言,我想不出有什么好的理由可以将你的代码分离到一个引擎中,而不用隔离命名空间 – 它本质上只是给你两个紧密耦合的应用程序共享相同的文件结构,所有的冲突和代码泄漏这需要。

我见过的每一个文档都演示了--mountable选项,而且当前的边缘指南强烈build议你包含isolate namespace – 这与使用--mountable over --full

最后还有术语混淆:不幸的是, rails plugin -h显示了以下描述:

[–full]#生成捆绑Rails应用程序的Rails 引擎进行testing
[–mountable]#生成可安装的独立应用程序

这给人的印象是,你使用--full来创build一个“引擎”,并且--mountable可以创build一个叫做“可挂载应用程序”的东西,实际上它们都是引擎 – 一个是命名空间,另一个不是。 这肯定会导致混淆,因为用户想要创build引擎可能会认为 – --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 

我对这个区别的理解是,引擎就像插件,并为现有的应用程序添加function。 虽然可挂载应用程序本质上是一个应用程序,并且可以独立使用

所以,如果你想能够自己运行或者在另一个应用程序中运行,你可以制作一个可安装的应用程序。 如果您打算将其作为现有应用程序的补充,但不能自行运行,则可以将其作为引擎。

不同的是,我相信,一个可安装的应用程序与主机应用程序是隔离的,所以他们不能共享类 – 模型,帮手等。这是因为一个可挂载应用程序是一个机架端点(即机架应用程序本身)。

免责声明:我最喜欢的只是刚开始玩Rails 3.1。

Interesting Posts