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.