121

Railsエンジンとマウント可能なアプリの違いを誰かが理解するのを手伝ってもらえますか?Rails 3.1では、「 rails newplugin___ コマンドを使用してどちらかを作成できます。

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

いつ一方を他方に対して使用したいですか?たとえば、エンジンを宝石としてパッケージ化できることは知っています。マウント可能なアプリの場合はそうではありませんか?他にどのような違いがありますか?

4

5 に答える 5

145

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

フルエンジン

フルエンジンの場合、親アプリケーションはエンジンからルートを継承します。で何も指定する必要はありません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 

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

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

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

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

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

私の想定から外れている場合は、誰かが私に知らせてください。私はこの応答を修正します。私はここで主題についての小さな記事を作りました 乾杯!

于 2011-07-26T16:22:15.447 に答える
43

どちらのオプションもエンジンを生成します。違いは--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 / 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 / asserts / javascripts / my_mountable_engine /application.js
create config / routers.rb create lib / my_mountable_engine.rb
create lib / tasks / my_mountable_engine.rake
create lib / my_mountable_engine / version .rb
lib / my_mountable_engine/engine.rbを作成します


説明

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

私が見たすべてのドキュメントは--mountableオプションを示しており、実際、現在のエッジガイドでは、これを含めることを強くお勧めしています。これは、useoverと言ってisolate namespaceいるのと同じです。--mountable--full

最後に、用語の混乱があります。残念ながらrails plugin -h、次の説明が表示されます。

[--full]#テスト用にバンドルされたRailsアプリケーションを使用してRailsエンジン
を生成します [--mountable]#マウント可能な分離アプリケーションを生成します

--fullこれは、「エンジン」を作成し、「マウント可能なアプリケーション」と呼ばれる別のものを作成するために使用する印象を与えます--mountable。実際には、両方がエンジンであり、一方は名前空間であり、もう一方はそうではありません。--fullエンジンを作成しようとしているユーザーは、それがより適切なオプションであると想定する可能性が高いため、これは混乱を招くことになります。

結論

  • rails plugin new something --full=アプリの名前空間のエンジン。(なぜあなたは?)
  • rails plugin new something --mountable=独自の名前空間を持つエンジン。(素晴らしい)

参考文献

于 2013-06-23T17:34:42.950 に答える
17

私は同じことを考えていたので、ここに行き着きました。以前の回答は基本的に質問をカバーしているように私には思えますが、私は次のことも役立つかもしれないと思いました:

# 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
于 2012-09-25T07:57:20.657 に答える
8

違いについての私の理解は、エンジンはプラグインのようなものであり、既存のアプリケーションに機能を追加するということです。マウント可能なアプリは本質的にアプリケーションであり、スタンドアロンにすることができます。

したがって、単独で、または別のアプリケーション内で実行できるようにする場合は、マウント可能なアプリを作成します。それを既存のアプリケーションへの追加にするつもりであるが、それ自体では実行しない場合は、それをエンジンにします。

于 2011-07-09T08:11:54.853 に答える
2

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

免責事項:私は、ほとんどの場合と同様に、Rails3.1をいじり始めたばかりです。

于 2011-06-02T09:47:38.753 に答える