web-dev-qa-db-ja.com

Rails 3.1:Engine vs. Mountable App

Rails Engineとマウント可能なアプリの違いを理解してくれる人はいますか?Rails 3.1では、「Rails新しいプラグイン- ___ "コマンド。

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

どちらを使用するかはいつですか? Engineを宝石としてパッケージ化できることは知っています。マウント可能なアプリの場合ではありませんか?他にどんな違いがありますか?

119
Jeremy Raines

私は次のことに気づきました:

フルエンジン

完全なエンジンでは、親アプリケーションはエンジンからルートを継承します。 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 

モデル、コントローラーなどは親アプリケーションから分離されていますが、ヘルパーは簡単に共有できます。

これらは私が見つけた主な違いです。おそらく他にありますか? here で尋ねましたが、まだ返事がありません。

私の印象では、完全なエンジンは親アプリケーションから分離されないため、親アプリに隣接するスタンドアロンアプリケーションとして使用するのが最適です。名前の衝突が起こる可能性があると思います。

マウント可能なエンジンは、名前の競合を回避し、親アプリケーションの特定の1つのルートにエンジンをバンドルする場合に使用できます。たとえば、カスタマーサービス用に設計された最初のエンジンの構築に取り組んでいます。親アプリケーションは、次のような単一のルートで機能をバンドルできます。

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

私の仮定がうまくいかない場合は、誰かが私に知らせてください、私はこの応答を修正します。私はこのテーマに関する小さな記事を作成しました ここ 乾杯!

140
astjohn

両方のオプションが 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)コントローラー、ヘルパー、ビュー、アセットのファイル構造は名前空間になります:

create app/controllers /my_mountable_engine/ application_controller.rb
create app/helpers /my_mountable_engine/ application_helper.rb
アプリ/メーラーの作成アプリ/モデルの作成
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
lib/tasks/my_mountable_engine.rakeを作成します
create lib/my_mountable_engine/version.rb
create lib/my_mountable_engine/engine.rb


説明

--fullオプションの使用例は非常に限られているようです。個人的には、名前空間も分離せずにコードをエンジンに分離したい理由を考えることはできません-基本的には、同じファイル構造とすべての競合とコード漏洩を共有する2つの密結合アプリケーションを提供するだけですそれが伴います。

私が見たすべてのドキュメントは--mountableオプションを示しており、実際に エッジガイドisolate namespace-を含めることを強くお勧めします。これはuse --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

違いは、マウント可能なアプリはホストアプリから分離されているため、クラス、モデル、ヘルパーなどを共有できないことです。これは、マウント可能なアプリがラックエンドポイントであるためです)。

免責事項:私は、ほとんどの場合と同じように、Rails 3.1。

2
Kris