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

发布于 2024-11-10 03:34:35 字数 307 浏览 5 评论 0 原文

有人可以帮助我理解 Rails 引擎和可安装应用程序之间的区别吗?在 Rails 3.1 中,您可以使用“rails new plugin ___”命令创建任一插件。

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

您什么时候想使用其中一种而不是另一种?我知道您可以将引擎打包为宝石。可安装应用程序不就是这样吗?还有哪些其他区别?

Can someone help me understand the differences between a Rails Engine and a Mountable app? In Rails 3.1, you can create either one with the "rails new plugin ___" command.

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

When would you want to use one versus the other? I know you can package an Engine as a gem, for one. Is that not the case for Mountable Apps? What other differences are there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

慵挽 2024-11-17 03:34:35

我注意到以下内容:

完整引擎

使用完整引擎,父应用程序会继承引擎的路由。无需在 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" 

如果我的假设偏离了我的假设,请有人告诉我,我将修复此响应。我写了一篇关于该主题的小文章 这里

I have noticed the following:

Full Engine

With a full engine, the parent application inherits the routes from the engine. It is not necessary to specify anything in parent_app/config/routes.rb. Specifying the gem in Gemfile is enough for the parent app to inherit the models, routes etc. The engine routes are specified as:

# my_engine/config/routes.rb 
Rails.application.routes.draw do 
  # whatever 
end 

No namespacing of models, controllers, etc. These are immediately
accessible to the parent application.

Mountable Engine

The engine's namespace is isolated by default:

# my_engine/lib/my_engine/engine.rb
module MyEngine 
  class Engine < Rails::Engine 
    isolate_namespace MyEngine 
  end 
end

With a mountable engine, the routes are namespaced and the parent app can bundle this functionality under a single route:

# 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 

Models, controllers, etc are isolated from the parent application - although helpers can be shared easily.

These are the main differences I have spotted. Perhaps there are others? I have asked over here, but have yet to receive a response.

My impression is that since a full engine does not isolate itself from the parent application, it is best used as a standalone application adjacent to the parent app. I believe name clashes could occur.

A mountable engine could be used in situations where you want to avoid name conflicts and bundle the engine under one specific route in the parent application. For example, I am working on building my first engine designed for customer service. The parent application could bundle it's functionality under a single route such as:

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

If I'm way off in my assumptions, someone please let me know and I'll fix this response. I have made a small article about the subject here.

她比我温柔 2024-11-17 03:34:35

这两个选项都会生成一个引擎。不同之处在于 --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/views/layouts/my_mountable_engine/application.html.erb
创建应用程序/资产/图像/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/version.rb
创建 lib/my_mountable_engine/engine.rb


说明

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

我见过的每一篇文档都演示了 --mountable 选项,实际上是当前的 边缘指南 强烈鼓励您包含隔离命名空间 - 这与使用 --mountable 而不是 相同 - -完整

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

[--full] # 生成一个带有捆绑 Rails 应用程序的 rails 引擎用于测试
[--mountable] # 生成可安装的隔离应用程序

这给人的印象是您使用 --full 创建一个“引擎”,并使用 --mountable 创建其他称为“可安装的应用程序”,而实际上它们都是引擎 - 一个具有命名空间,一个没有。这必然会导致混乱,因为希望创建引擎的用户可能会认为 --full 是更相关的选项。

结论

  • rails 插件新东西 --full = 应用程序命名空间中的引擎。 (为什么要这样做?)
  • rails 插件新东西 --mountable = 具有自己的命名空间的引擎。 (太棒了)

参考文献

Both options will generate an engine. The difference is that --mountable will create the engine in an isolated namespace, whereas --full will create an engine that shares the namespace of the main app.

The differences will be manifested in 3 ways:

1) The engine class file will call 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) The engine's config/routes.rb file will be namespaced:

Full engine:

Rails.application.routes.draw do
end

Mounted engine:

MyMountableEngine::Engine.routes.draw do
end

3) The file structure for controllers, helpers, views, and assets will be namespaced:

create app/controllers/my_mountable_engine/application_controller.rb
create app/helpers/my_mountable_engine/application_helper.rb
create app/mailers create app/models
create app/views/layouts/my_mountable_engine/application.html.erb
create app/assets/images/my_mountable_engine
create app/assets/stylesheets/my_mountable_engine/application.css
create app/assets/javascripts/my_mountable_engine/application.js
create config/routes.rb create lib/my_mountable_engine.rb
create lib/tasks/my_mountable_engine.rake
create lib/my_mountable_engine/version.rb
create lib/my_mountable_engine/engine.rb


Explanation

The use case for the --full option seems to be very limited. Personally I can't think of any good reason why you'd want to separate your code into an engine without isolating the namespace as well- It would essentially just give you two tightly coupled applications sharing identical file structures and all the conflicts and code leakage that entails.

Every piece of documentation I've seen demonstrates the --mountable option, and indeed the current edge guide strongly encourages you to include isolate namespace- which is the same as saying use --mountable over --full.

Finally there's terminology confusion: Unfortunately rails plugin -h shows the following descriptions:

[--full] # Generate a rails engine with bundled Rails application for testing
[--mountable] # Generate mountable isolated application

This gives the impression that you use --full to create an "engine" and --mountable to create something else called a "mountable application", when in fact they're both engines - one namespaced and one not. That's bound to lead to confusion as users looking to create an engine will likely assume that --full is the more relevant option.

Conclusion

  • rails plugin new something --full = Engine in your app's namespace. (Why would you?)
  • rails plugin new something --mountable = Engine with it's own namespace. (Awesome)

References

迷爱 2024-11-17 03:34:35

我也想知道,因此,最终来到了这里。在我看来,早期的答案基本上涵盖了这个问题,但我认为以下内容也可能有所帮助:(

# 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

i was wondering the same and, hence, ended up here. it seems to me that the earlier answers basically cover the question, but i thought the following might help as well:

# 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

of particular interest (to me) is the fact that there is no difference between

rails plugin new test-plugin -T --mountable

and

rails plugin new test-plugin -T --full --mountable
故乡的云 2024-11-17 03:34:35

我对差异的理解是引擎就像插件一样,可以为现有应用程序添加功能。虽然可安装应用程序本质上是一个应用程序,并且可以独立存在。

因此,如果您希望能够单独运行它或在另一个应用程序中运行它,您将创建一个可安装的应用程序。如果您打算将其添加到现有应用程序中,但不单独运行,则可以将其设为引擎。

My understanding of the difference is that engines are like plugins, and add functionality to existing applications. While mountable apps are essentially an application, and can stand alone.

So if you want to be able to run it by itself or within another application you would make a mountable app. If you intend for it to be an addition to existing applications, but not run by itself you would make it an engine.

时光暖心i 2024-11-17 03:34:35

我认为,区别在于可安装应用程序与主机应用程序是隔离的,因此它们不能共享类 - 模型、帮助程序等。这是因为可安装应用程序是一个机架端点(即本身就是一个机架应用程序) )。

免责声明:像大多数人一样,我才刚刚开始使用 Rails 3.1。

The difference, I believe, is that a mountable app's are isolated from the host app, so they can't share classes - models, helper etc. This is because a Mountable app is a Rack endpoint (i.e a Rack app in its own right).

Disclaimer: I have, like most, only just started toying with Rails 3.1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文