有人可以帮助我了解Rails Engine和可安装应用之间的区别吗?在Rails 3.1中,您可以使用“ rails new plugin _ __ ”命令创建一个。
rails plugin new forum --full # Engine
rails plugin new forum --mountable # Mountable App
您什么时候要使用一个相对于另一个?我知道您可以将Engine打包为gem。可挂载应用程序不是这种情况吗?还有什么其他区别?
有人可以帮助我了解Rails Engine和可安装应用之间的区别吗?在Rails 3.1中,您可以使用“ rails new plugin _ __ ”命令创建一个。
rails plugin new forum --full # Engine
rails plugin new forum --mountable # Mountable App
您什么时候要使用一个相对于另一个?我知道您可以将Engine打包为gem。可挂载应用程序不是这种情况吗?还有什么其他区别?
Answers:
我注意到以下几点:
全引擎
使用完整的引擎,父应用程序将从引擎继承路由。没有必要在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"
如果我的假设与您相去甚远,请告诉我,我将解决此问题。我在这里 干了一篇关于这个主题的小文章!
mount MyEngine::Engine => "/"
。它适用于资源,也许引擎也适用。
这两个选项都会生成一个引擎。不同之处在于,--mountable
它将在隔离的名称空间中--full
创建引擎,而将创建共享主应用程序名称空间的引擎。
差异将通过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)控制器,助手,视图和资产的文件结构将被命名为:
创建app / controllers / my_mountable_engine /application_controller.rb
创建app / helpers / my_mountable_engine /application_helper.rb
创建app / mailers创建app /模型
创建app / views / layouts / my_mountable_engine /application.html.erb
创建app / assets / images / my_mountable_engine
创建app / assets / stylesheets / my_mountable_engine /application.css
创建app / assets / javascripts / my_mountable_engine /application.js
创建config / routes.rb创建lib / my_mountable_engine.rb
创建lib / tasks / my_mountable_engine.rake 创建lib / my_mountable_engine / engine .rb
创建lib / my_mountable_engine / version .rb
该--full
选项的用例似乎非常有限。就我个人而言,我想不出为什么要在不隔离名称空间的情况下将代码分离到引擎中的任何好理由-从本质上来说,这只是给您两个紧密耦合的应用程序,它们共享相同的文件结构以及所有冲突和代码泄漏这需要。
我看过的每篇文档都演示了该--mountable
选项,实际上,当前的边缘指南强烈建议您加入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
=具有它自己的名称空间的引擎。(真棒)--full
:如果您拥有Rails网站的一部分,则希望保持集成(而不是在隔离的命名空间中),并且仍要在不同的Rails项目之间共享。它也可以比这更简单:也许您的gem没有添加那么多,但是您希望能够正确地将其连接。
Admin::AdminService.some_action
但如果其他客户端应用程序(例如Ember应用程序)使用与您的代码相关的路由,则不必更改路由想隔离。--full似乎是一个中间步骤,可能更容易实现。
我在想同样的事情,因此就到这里了。在我看来,以前的答案基本上涵盖了这个问题,但我认为以下内容可能也会有所帮助:
# 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
--full
优先于--mountable
?
我认为,区别在于可挂载应用程序与主机应用程序是隔离的,因此它们无法共享类(模型,助手等)。这是因为可挂载应用程序是Rack端点(即,Rack应用程序本身就是)。
免责声明:与大多数人一样,我只是刚刚开始使用Rails 3.1。