Rails 3.1 : 엔진 vs. 마운트 가능한 앱


120

누군가가 Rails Engine과 Mountable 앱의 차이점을 이해하도록 도울 수 있습니까? Rails 3.1에서는 "rails new plugin _ __ "명령으로 둘 중 하나를 생성 할 수 있습니다 .

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

언제 하나를 사용하고 싶습니까? 엔진을 보석으로 패키지화 할 수 있다는 것을 알고 있습니다. Mountable Apps의 경우가 아닌가요? 다른 차이점은 무엇입니까?

답변:


143

다음을 발견했습니다.

전체 엔진

전체 엔진을 사용하는 경우 상위 애플리케이션은 엔진에서 경로를 상속합니다. 에서 아무것도 지정할 필요가 없습니다 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" 

내 가정에서 벗어난 경우 누군가 알려 주시면이 응답을 수정하겠습니다. 여기 에 주제에 대한 작은 기사를 만들었습니다. 건배!


1
탑재 가능한 엔진을 상위 앱의 루트에서 라우팅 / 마운트 할 수 있습니까?
— Slick23

3
@JustinM 시도 할 수 mount MyEngine::Engine => "/"있습니다. 자원을 위해 작동합니다. 아마도 엔진에서도 마찬가지입니다.
— Benoit Garret 2011 년

2
@astjohn 블로그에 대한 훌륭한 요약입니다. 하지만 그 반대가 아닐까요? Full Engine이 "불완전"하고 작동하려면 상위 앱이 필요한 반면 Mountable Engine은 상위 앱에서 "격리"되어 있기 때문에 독립형으로 작동 할 수 있습니까?
— 테오 Scholiadis

39

두 옵션 모두 엔진 을 생성합니다 . 차이점은 --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 / 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
lib / my_mountable_engine / engine.rb 생성


설명

--full옵션 의 사용 사례는 매우 제한적인 것 같습니다. 개인적으로 네임 스페이스를 분리하지 않고 코드를 엔진으로 분리하려는 이유는 생각할 수 없습니다. 기본적으로 동일한 파일 구조와 모든 충돌 및 코드 누출을 공유하는 두 개의 밀접하게 결합 된 애플리케이션 만 제공합니다. 수반합니다.

내가 본 문서의 모든 부분이 --mountable옵션을 보여주고 있으며 , 실제로 현재 엣지 가이드 는 포함 할 것을 강력히 권장합니다. isolate namespace이것은 use --mountableover 를 말하는 것과 같습니다 --full.

마지막으로 용어 혼동이 있습니다. 불행히도 rails plugin -h다음 설명이 표시됩니다.

[--full] # 테스트를 위해 번들로 제공되는 Rails 애플리케이션으로 Rails 엔진 생성
[--mountable] # 마운트 가능한 격리 된 애플리케이션 생성

이것은 --full"엔진" --mountable을 만들고 "마운트 가능한 응용 프로그램"이라고하는 다른 것을 만드는 데 사용하는 인상을줍니다. 실제로 둘 다 엔진 인 경우 (하나는 네임 스페이스가 있고 다른 하나는 아님). 엔진을 만들려는 사용자 --full가 이것이 더 관련성있는 옵션 이라고 생각할 가능성이 높기 때문에 혼란을 야기 할 수 있습니다.

결론

  • rails plugin new something --full= 앱 네임 스페이스의 엔진. (왜 당신은?)
  • rails plugin new something --mountable= 자체 네임 스페이스가있는 엔진. (대박)

참고 문헌


9
사용하는 한 가지 좋은 이유가 있습니다 --full. Rails 웹 사이트의 일부가 통합 된 상태를 유지하고 (분리 된 네임 스페이스가 아닌) 여전히 다른 Rails 프로젝트간에 공유하려는 경우입니다. 또한 그것은 그것보다 더 간단 할 수 있습니다 : 아마도 당신의 gem은 그다지 많이 추가하지 않지만 올바르게 연결할 수 있기를 원할 것입니다.
— nathanvda

2
@nathanvda - 오른쪽,하지만 난 생각한다면 당신은 정말 여러 프로젝트에 걸쳐있는 거 공유 뭔가 해야 당신이 기본적으로 플러그인으로 사용하고 있기 때문에 네임 스페이스 수,
— Yarin

파일을 분리하려면 --full을 사용하고, Admin::AdminService.some_action그렇지 않을 때 호출 사이트의 네임 스페이스를 지정 하고, Ember 앱과 같은 다른 클라이언트 측 응용 프로그램이 코드와 관련된 경로를 사용하는 경우 경로를 변경할 필요가 없다고 생각합니다. 격리하고 싶습니다. --full은 구현하기 더 쉬운 중간 단계처럼 보입니다.
— Jwan622

저는 현재 국가 별 규정을 처리해야하지만 동일한 인터페이스를 전 세계에 노출하는 국제 응용 프로그램을 작업 중입니다. 국가 당 하나의 "Core"인스턴스가 있으므로 한 번에 모두 처리 할 필요가 없습니다. "국가 엔진"은 그 자체로는 의미가 없으므로 "핵심"앱과의 결합은 문제가되지 않습니다. 그러나 핵심 앱이 어떤 국가에서 작동하는지 알 수 없기 때문에 자체 네임 스페이스에있는 것을 원하지 않습니다. "완전한"엔진은 파일과 클래스를 모듈 방식으로 구성하는 것과 비슷하지만 "모놀리스"는 그대로 유지합니다.
— Mankalas

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

아마도 --full우선권 이 있기 때문 --mountable일까요?
— Mankalas

8

차이점에 대한 나의 이해는 엔진이 플러그인과 같으며 기존 애플리케이션에 기능을 추가한다는 것입니다. 탑재 가능한 앱은 기본적으로 애플리케이션이며 단독으로 사용할 수 있습니다.

따라서 자체적으로 또는 다른 응용 프로그램 내에서 실행할 수 있도록하려면 탑재 가능한 앱을 만듭니다. 기존 애플리케이션에 추가하고 싶지만 자체적으로 실행하지 않으려면 엔진으로 만들 것입니다.


2

차이점은 마운트 가능한 앱이 호스트 앱과 분리되어 있기 때문에 모델, 도우미 등의 클래스를 공유 할 수 없다는 것입니다. 이는 마운트 가능한 앱이 랙 엔드 포인트 (즉, 자체적으로 랙 앱)이기 때문입니다. ).

면책 조항 : 대부분과 마찬가지로 저는 Rails 3.1을 사용하기 시작했습니다.


동의합니다. 이상하게 보이는 한 가지는 기본적으로 Engine은 "models"폴더를 제공하지만 Mountable App은 제공하지 않는다는 것입니다. 은 "가장 좋은 방법"이 포함 앱 모델을 만들 발전기를하는 것입니다 경우 엔진 / moutable의 모든 마이그레이션하고 싶지 않을 것처럼 보이기 때문에 나는 궁금해
— 제레미 레인즈
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.