엔진 시작하기
이 가이드에서는 엔진에 대해 알아보고 어떻게 호스트 애플리케이션에 추가 기능을 제공할 수 있는지 배울 것입니다.
이 가이드를 읽고 나면 다음을 알 수 있습니다:
- 엔진이란 무엇인지.
- 엔진을 생성하는 방법.
- 엔진에 기능을 추가하는 방법.
- 애플리케이션에 엔진을 연결하는 방법.
- 애플리케이션에서 엔진 기능을 재정의하는 방법.
- 로드 및 구성 훅을 사용하여 Rails 프레임워크를 로드하지 않는 방법.
엔진이란?
엔진은 호스트 애플리케이션에 기능을 제공하는 “미니 애플리케이션"으로 간주될 수 있습니다. Rails 애플리케이션은 실제로 Rails::Application
클래스가 Rails::Engine
의 많은 동작을 상속받는 "강화된” 엔진에 불과합니다.
따라서 엔진과 애플리케이션은 미묘한 차이점을 제외하고는 거의 동일한 것으로 간주될 수 있습니다. 엔진과 애플리케이션은 공통 구조를 공유합니다.
엔진은 플러그인과도 밀접한 관련이 있습니다. 두 가지 모두 공통 lib
디렉토리 구조를 가지고 있으며 rails plugin new
생성기를 사용하여 생성됩니다. 차이점은 엔진이 Rails에 의해 “완전한 플러그인"으로 간주된다는 것입니다(생성기 명령에 전달되는 --full
옵션에 의해 표시됨). 여기서는 --mountable
옵션을 사용할 것이며, 이 옵션에는 --full
의 모든 기능이 포함되어 있습니다. 이 가이드에서는 이러한 "완전한 플러그인"을 일반적으로 "엔진"이라고 합니다. 엔진은 플러그인이 될 수 있고, 플러그인은 엔진이 될 수 있습니다.
이 가이드에서 생성할 엔진의 이름은 "blorgh"입니다. 이 엔진은 호스트 애플리케이션에 블로깅 기능을 제공하여 새 기사와 댓글을 작성할 수 있게 합니다. 이 가이드의 시작 부분에서는 엔진 자체 내에서만 작업할 것이지만, 나중 섹션에서는 애플리케이션에 연결하는 방법을 살펴볼 것입니다.
엔진은 또한 호스트 애플리케이션에서 격리될 수 있습니다. 이는 애플리케이션이 articles_path
와 같은 라우팅 헬퍼 경로를 가질 수 있고 엔진도 articles_path
라는 경로를 제공할 수 있지만, 두 경로가 충돌하지 않는다는 것을 의미합니다. 이와 함께 컨트롤러, 모델 및 테이블 이름도 네임스페이스화됩니다. 이에 대해서는 이 가이드의 라우팅 섹션에서 자세히 설명합니다.
항상 애플리케이션이 엔진에 우선한다는 것을 명심해야 합니다. 애플리케이션은 자신의 환경에서 최종 결정권을 가집니다. 엔진은 애플리케이션을 크게 변경하는 것이 아니라 향상시키는 역할을 해야 합니다.
다른 엔진의 데모를 보려면 Devise, Thredded, Spree, Refinery CMS를 확인하세요.
마지막으로, 엔진은 James Adam, Piotr Sarnacki, Rails Core Team 및 기타 많은 사람들의 노력 없이는 불가능했을 것입니다. 이들을 만나면 감사의 말을 잊지 마세요!
엔진 생성하기
엔진을 생성하려면 플러그인 생성기를 실행하고 필요에 따라 적절한 옵션을 전달해야 합니다. "blorgh” 예제의 경우 “마운트 가능한” 엔진을 만들어야 하므로 다음 명령을 터미널에서 실행합니다:
$ rails plugin new blorgh --mountable
플러그인 생성기의 전체 옵션 목록은 다음 명령을 입력하여 확인할 수 있습니다:
$ rails plugin --help
--mountable
옵션은 “마운트 가능"하고 네임스페이스로 격리된 엔진을 만들고 싶다는 것을 생성기에 알려줍니다. 이 생성기는 --full
옵션을 사용하는 것과 동일한 골격 구조를 제공합니다. --full
옵션은 다음과 같은 엔진을 생성하도록 지시합니다:
app
디렉토리 트리config/routes.rb
파일:Rails.application.routes.draw do end
lib/blorgh/engine.rb
에 있는 파일로, 표준 Rails 애플리케이션의config/application.rb
파일과 기능이 동일합니다:module Blorgh class Engine < ::Rails::Engine end end
--mountable
옵션은 --full
옵션에 다음을 추가합니다:
- 자산 매니페스트 파일(
blorgh_manifest.js
및application.css
) - 네임스페이스화된
ApplicationController
스텁 - 네임스페이스화된
ApplicationHelper
스텁 - 엔진의 레이아웃 뷰 템플릿
config/routes.rb
의 네임스페이스 격리:Blorgh::Engine.routes.draw do end
lib/blorgh/engine.rb
의 네임스페이스 격리:module Blorgh class Engine < ::Rails::Engine isolate_namespace Blorgh end end
또한 --mountable
옵션은 생성기에게 test/dummy
위치의 더미 테스트 애플리케이션 내에 엔진을 마운트하도록 지시합니다. 이는 test/dummy/config/routes.rb
파일에 다음 내용을 추가합니다:
mount Blorgh::Engine => "/blorgh"
엔진 내부
중요한 파일
이 새로운 엔진의 루트 디렉토리에는 blorgh.gemspec
파일이 있습니다. 나중에 애플리케이션에 엔진을 포함할 때 다음 줄을 Rails
애플리케이션의 Gemfile
에 추가할 것입니다:
gem "blorgh", path: "engines/blorgh"
bundle install
을 실행하는 것을 잊지 마세요. Gemfile
에 gem을 지정하면 Bundler가 이를 gem으로 로드하고 blorgh.gemspec
파일을 구문 분석하며 lib
디렉토리의 lib/blorgh.rb
파일을 요구합니다. 이 파일은 lib/blorgh/engine.rb
파일(위치: lib/blorgh/engine.rb
)을 요구하고 Blorgh
라는 기본 모듈을 정의합니다.
require "blorgh/engine" module Blorgh end
팁: 일부 엔진은 이 파일을 사용하여 엔진의 전역 구성 옵션을 설정합니다. 이는 상당히 좋은 아이디어이므로 구성 옵션을 제공하려면 엔진의 module
이 정의된 파일이 완벽한 장소입니다. 모듈 내에 메서드를 배치하면 됩니다.
lib/blorgh/engine.rb
내에는 엔진의 기본 클래스가 있습니다:
module Blorgh class Engine < ::Rails::Engine isolate_namespace Blorgh end end
Rails::Engine
클래스를 상속함으로써 이 gem은 지정된 경로에 엔진이 있음을 Rails에 알리고 엔진을 애플리케이션 내에 올바르게 마운트하며 모델, 메일러, 컨트롤러 및 뷰의 로드 경로에 엔진의 app
디렉토리를 추가하는 등의 작업을 수행합니다.
여기서 isolate_namespace
메서드에 특별한 주의를 기울일 필요가 있습니다. 이 호출은 컨트롤러, 모델, 라우팅 및 기타 항목을 자체 네임스페이스로 격리하여 애플리케이션 내부와 분리하는 역할을 합니다. 그렇지 않으면 엔진의 구성 요소가 애플리케이션으로 "누출"되어 원치 않는 혼란을 일으키거나 중요한 엔진 구성 요소가 애플리케이션 내의 유사한 이름의 항목에 의해 재정의될 수 있습니다. 이러한 충돌의 한 예는 헬퍼입니다. isolate_namespace
를 호출하지 않으면 엔진의 헬퍼가 애플리케이션의 컨트롤러에 포함될 수 있습니다.
참고: isolate_namespace
줄을 엔진 클래스 정의 내에 두는 것이 매우 권장됩니다. 그렇지 않으면 엔진에서 생성된 클래스가 애플리케이션과 충돌할 수 있습니다.
이 네임스페이스 격리가 의미하는 바는 bin/rails generate model
과 같은 호출로 생성된 모델이 Article
이 아닌 Blorgh::Article
로 불리게 된다는 것입니다. 또한 모델의 테이블 이름도 articles
가 아닌 blorgh_articles
가 됩니다. 모델 네임스페이싱과 유사하게 ArticlesController
라는 컨트롤러는 Blorgh::ArticlesController
가 되며, 해당 컨트롤러의 뷰는 app/views/articles
가 아닌 app/views/blorgh/articles
에 있습니다. 메일러, 작업 및 헬퍼도 네임스페이스화됩니다.
마지막으로, 라우팅도 엔진 내에서 격리됩니다. 이는 네임스페이싱의 가장 중요한 부분 중 하나이며 이 가이드의 라우팅 섹션에서 자세히 설명됩니다.
app
디렉토리
app
디렉토리에는 assets
, controllers
, helpers
, jobs
, mailers
, models
및 views
디렉토리가 있으며, 이는 애플리케이션에서 익숙한 것과 유사합니다. 모델에 대해서는 향후 섹션에서 자세히 살펴볼 것입니다.
app/assets
디렉토리에는 images
및 stylesheets
디렉토리가 있으며, 이 또한 애플리케이션과 유사합니다. 그러나 여기의 차이점은 각 디렉토리에 엔진 이름의 하위 디렉토리가 포함되어 있다는 것입니다. 이 엔진이 네임스페이스화될 것이므로 자산도 네임스페이스화해야 합니다.
app/controllers
디렉토리에는 blorgh
디렉토리가 있으며 이 디렉토리에는 application_controller.rb
라는 파일이 포함되어 있습니다. 이 파일은 엔진의 컨트롤러에 대한 공통 기능을 제공할 것입니다. blorgh
디렉토리는 엔진의 다른 네, 계속해서 번역하겠습니다.
app/controllers
디렉토리에는 blorgh
디렉토리가 있으며 이 디렉토리에는 application_controller.rb
라는 파일이 포함되어 있습니다. 이 파일은 엔진의 컨트롤러에 대한 공통 기능을 제공할 것입니다. blorgh
디렉토리는 엔진의 다른 컨트롤러가 위치할 곳입니다. 이 네임스페이스화된 디렉토리에 파일을 배치하면 다른 엔진이나 애플리케이션 내의 동일한 이름의 컨트롤러와 충돌할 가능성을 방지할 수 있습니다.
참고: 엔진 내의 ApplicationController
클래스는 애플리케이션의 ApplicationController
와 동일한 이름을 가지고 있어 애플리케이션을 엔진으로 변환하기 쉽습니다.
app/controllers
와 마찬가지로 app/helpers
, app/jobs
, app/mailers
및 app/models
디렉토리에도 공통 기능을 모으는 관련 application_*.rb
파일이 포함된 blorgh
하위 디렉토리가 있습니다. 파일을 이 하위 디렉토리에 배치하고 객체를 네임스페이스화하면 다른 엔진이나 애플리케이션 내의 동일한 이름의 요소와 충돌할 가능성을 방지할 수 있습니다.
마지막으로 app/views
디렉토리에는 layouts
폴더가 있으며 여기에는 blorgh/application.html.erb
라는 파일이 포함되어 있습니다. 이 파일을 사용하여 엔진의 레이아웃을 지정할 수 있습니다. 이 엔진을 독립형 엔진으로 사용하려는 경우 이 파일에 레이아웃에 대한 사용자 지정을 추가하면 됩니다. 애플리케이션의 app/views/layouts/application.html.erb
파일이 아닌 이 파일을 사용하면 됩니다.
엔진 사용자에게 레이아웃을 강요하고 싶지 않다면 이 파일을 삭제하고 엔진의 컨트롤러에서 다른 레이아웃을 참조할 수 있습니다.
bin
디렉토리
이 디렉토리에는 bin/rails
파일 하나가 포함되어 있으며, 이를 통해 애플리케이션 내에서와 마찬가지로 rails
하위 명령 및 생성기를 사용할 수 있습니다. 즉, 다음과 같은 명령을 실행하여 엔진에 새 컨트롤러와 모델을 쉽게 생성할 수 있습니다:
$ bin/rails generate model
물론 isolate_namespace
가 Engine
클래스에 있는 엔진 내에서 생성된 모든 것은 네임스페이스화된다는 점을 명심해야 합니다.
test
디렉토리
test
디렉토리는 엔진에 대한 테스트가 포함될 곳입니다. 엔진을 테스트하기 위해 test/dummy
에 축소된 버전의 Rails 애플리케이션이 포함되어 있습니다. 이 애플리케이션은 test/dummy/config/routes.rb
파일에서 엔진을 마운트합니다:
Rails.application.routes.draw do mount Blorgh::Engine => "/blorgh" end
이 줄은 엔진을 /blorgh
경로에 마운트하여 애플리케이션을 통해서만 해당 경로에서 엔진에 액세스할 수 있게 합니다.
테스트 디렉토리 내에는 test/integration
디렉토리가 있으며, 여기에 엔진에 대한 통합 테스트를 배치해야 합니다. 또한 test
디렉토리에 다른 디렉토리를 만들 수 있습니다. 예를 들어 test/models
디렉토리를 만들어 모델 테스트를 배치할 수 있습니다.
엔진 기능 제공하기
이 가이드에서 다루는 엔진은 기사 제출 및 댓글 기능을 제공하며 시작하기 가이드와 유사한 흐름을 따릅니다.
참고: 이 섹션에 대해서는 blorgh
엔진의 루트 디렉토리에서 명령을 실행하세요.
기사 리소스 생성하기
블로그 엔진에 필요한 첫 번째 것은 Article
모델과 관련 컨트롤러입니다. 이를 빠르게 생성하려면 Rails 스캐폴드 생성기를 사용할 수 있습니다.
$ bin/rails generate scaffold article title:string text:text
이 명령은 다음과 같은 출력을 생성합니다:
invoke active_record create db/migrate/[timestamp]_create_blorgh_articles.rb create app/models/blorgh/article.rb invoke test_unit create test/models/blorgh/article_test.rb create test/fixtures/blorgh/articles.yml invoke resource_route route resources :articles invoke scaffold_controller create app/controllers/blorgh/articles_controller.rb invoke erb create app/views/blorgh/articles create app/views/blorgh/articles/index.html.erb create app/views/blorgh/articles/edit.html.erb create app/views/blorgh/articles/show.html.erb create app/views/blorgh/articles/new.html.erb create app/views/blorgh/articles/_form.html.erb create app/views/blorgh/articles/_article.html.erb invoke resource_route invoke test_unit create test/controllers/blorgh/articles_controller_test.rb create test/system/blorgh/articles_test.rb invoke helper create app/helpers/blorgh/articles_helper.rb invoke test_unit
스캐폴드 생성기가 수행하는 첫 번째 작업은 active_record
생성기를 호출하는 것입니다. 이는 리소스에 대한 마이그레이션과 모델을 생성합니다. 그러나 여기서 주목할 점은 마이그레이션의 이름이 일반적인 create_articles
가 아닌 create_blorgh_articles
라는 것입니다. 이는 Engine
클래스 정의에 있는 isolate_namespace
메서드 때문입니다. 모델 또한 app/models/article.rb
가 아닌 app/models/blorgh/article.rb
에 배치되어 네임스페이스화됩니다.
다음으로 test_unit
생성기가 이 모델에 대해 호출되어 test/models/blorgh/article_test.rb
(일반적인 test/models/article_test.rb
가 아님)에 모델 테스트를 생성하고 test/fixtures/blorgh/articles.yml
(일반적인 test/fixtures/articles.yml
가 아님)에 fixture를 생성합니다.
그 다음에는 config/routes.rb
파일에 리소스에 대한 라인이 삽입됩니다. 이 라인은 단순히 resources :articles
이며, 엔진의 config/routes.rb
파일을 다음과 같이 만듭니다:
Blorgh::Engine.routes.draw do resources :articles end
여기서 주목할 점은 라우팅이 YourApp::Application
클래스가 아닌 Blorgh::Engine
객체에 그려진다는 것입니다. 이는 엔진 라우팅이 엔진 자체에 국한되고 테스트 디렉토리 섹션에 표시된 대로 특정 지점에 마운트될 수 있도록 하기 위함입니다. 또한 애플리케이션의 라우팅과 엔진의 라우팅이 격리되도록 합니다. 이에 대한 자세한 내용은 이 가이드의 라우팅 섹션에서 설명합니다.
다음으로 scaffold_controller
생성기가 호출되어 Blorgh::ArticlesController
(위치: app/controllers/blorgh/articles_controller.rb
)라는 컨트롤러와 app/views/blorgh/articles
의 관련 뷰를 생성합니다. 이 생성기는 또한 컨트롤러 테스트(test/controllers/blorgh/articles_controller_test.rb
및 test/system/blorgh/articles_test.rb
)와 헬퍼(app/helpers/blorgh/articles_helper.rb
)를 생성합니다.
이 생성기가 만든 모든 것은 깔끔하게 네임스페이스화되어 있습니다. 컨트롤러의 클래스는 Blorgh
모듈 내에 정의됩니다:
module Blorgh class ArticlesController < ApplicationController # ... end end
참고: ArticlesController
클래스는 애플리케이션의 ApplicationController
가 아닌 Blorgh::ApplicationController
를 상속합니다.
app/helpers/blorgh/articles_helper.rb
의 헬퍼도 네임스페이스화되어 있습니다:
module Blorgh module ArticlesHelper # ... end end
이를 통해 다른 엔진이나 애플리케이션에 기사 리소스가 있는 경우에도 충돌을 방지할 수 있습니다.
엔진 루트에서 bin/rails db:migrate
를 실행하여 스캐폴드 생성기가 생성한 마이그레이션을 실행하고 bin/rails server
를 test/dummy
에서 실행하면 생성된 기본 스캐폴드를 볼 수 있습니다. 둘러보세요! 첫 번째 엔진의 첫 번째 기능을 생성했습니다.
콘솔에서 놀아보고 싶다면 bin/rails console
도 작동할 것입니다. 기억하세요: Article
모델은 네임스페이스화되어 있으므로 참조하려면 Blorgh::Article
로 호출해야 합니다.
irb> Blorgh::Article.find(1) => #<Blorgh::Article id: 1 ...>
마지막으로 이 엔진의 articles
리소스는 엔진의 루트가 되어야 합니다. 누군가가 엔진이 마운트된 루트 경로로 이동하면 기사 목록이 표시되어야 합니다. 이를 위해 엔진의 config/routes.rb
파일에 다음 줄을 삽입하면 됩니다:
root to: "articles#index"
이제 사람들은 기사를 보려면 /articles
가 아닌 엔진의 루트로 이동하면 됩니다. 즉, http://localhost:3000/blorgh/articles
대신 http://localhost:3000/blorgh
로 이동하면 됩니다.
댓글 리소스 생성하기
이제 엔진에서 새 기사를 생성할 수 있으므로 댓글 기능을 추가하는 것도 합리적입니다. 이를 위해 Comment
모델, 댓글 컨트롤러를 생성하고 기사 스캐폴드를 수정하여 댓글을 표시하고 새 댓글을 작성할 수 있게 해야 합니다.
엔진 루트에서 모델 생성기를 실행합니다. Comment
모델을 생성하고 관련 테이블에 article_id
정수와 text
텍스트 열을 만들도록 지시합니다.
$ bin/rails generate model Comment article_id:integer text:text
이 명령은 다음과 같은 출력을 생성합니다:
invoke active_record create db/migrate/[timestamp]_create_blorgh_comments.rb create app/models/blorgh/comment.rb invoke test_unit create test/models/blorgh/comment_test.rb create test/fixtures/blorgh/comments.yml
이 생성기 호출은 필요한 모델 파일만 생성하며 파일을 blorgh
디렉토리 아래에 네임스페이스화하고 Blorgh::Comment
라는 모델 클래스를 만듭니다. 이제 blorgh_comments
테이블을 만들기 위해네, 계속해서 번역하겠습니다.
이제 blorgh_comments
테이블을 만들기 위해 마이그레이션을 실행합니다:
$ bin/rails db:migrate
기사에 댓글을 표시하려면 app/views/blorgh/articles/show.html.erb
를 편집하고 "Edit” 링크 앞에 다음 줄을 추가합니다:
<h3>Comments</h3> <%= render @article.comments %>
이 줄은 Blorgh::Article
모델에 has_many
댓글 연결이 정의되어 있어야 한다는 것을 의미합니다. 현재는 그렇지 않습니다. 이를 정의하려면 app/models/blorgh/article.rb
를 열고 모델에 다음 줄을 추가합니다:
has_many :comments
이렇게 하면 모델이 다음과 같이 됩니다:
module Blorgh class Article < ApplicationRecord has_many :comments end end
참고: has_many
가 Blorgh
모듈 내부의 클래스 내에 정의되어 있기 때문에 Rails는 Blorgh::Comment
모델을 사용하려는 것을 알 수 있으므로 :class_name
옵션을 지정할 필요가 없습니다.
다음으로 기사에 댓글을 작성할 수 있는 폼이 필요합니다. 이를 추가하려면 app/views/blorgh/articles/show.html.erb
에서 render @article.comments
호출 아래에 다음 줄을 넣습니다:
<%= render "blorgh/comments/form" %>
그런 다음 이 줄이 렌더링할 partial이 존재해야 합니다. app/views/blorgh/comments
디렉토리를 새로 만들고 거기에 _form.html.erb
라는 새 파일을 만들어 필요한 partial을 만듭니다:
<h3>New comment</h3> <%= form_with model: [@article, @article.comments.build] do |form| %> <p> <%= form.label :text %><br> <%= form.text_area :text %> </p> <%= form.submit %> <% end %>
이 폼이 제출되면 엔진 내의 /articles/:article_id/comments
로 POST
요청을 시도할 것입니다. 이 경로는 아직 존재하지 않지만 config/routes.rb
의 resources :articles
줄을 다음과 같이 변경하여 만들 수 있습니다:
resources :articles do resources :comments end
이렇게 하면 댓글에 대한 중첩 경로가 생성됩니다. 이것이 폼에서 요구하는 바입니다.
경로는 존재하지만 이 경로로 가는 컨트롤러는 아직 없습니다. 이를 생성하려면 엔진 루트에서 다음 명령을 실행합니다:
$ bin/rails generate controller comments
이 명령은 다음과 같은 것을 생성합니다:
create app/controllers/blorgh/comments_controller.rb invoke erb exist app/views/blorgh/comments invoke test_unit create test/controllers/blorgh/comments_controller_test.rb invoke helper create app/helpers/blorgh/comments_helper.rb invoke test_unit
폼은 /articles/:article_id/comments
로 POST
요청을 보낼 것이며, 이는 Blorgh::CommentsController
의 create
액션에 해당합니다. 이 액션을 생성해야 합니다. app/controllers/blorgh/comments_controller.rb
의 클래스 정의 내에 다음 줄을 추가하면 됩니다:
def create @article = Article.find(params[:article_id]) @comment = @article.comments.create(comment_params) flash[:notice] = "Comment has been created!" redirect_to articles_path end private def comment_params params.require(:comment).permit(:text) end
새 댓글 폼을 작동시키는 데 필요한 마지막 단계입니다. 그러나 댓글 표시는 아직 제대로 작동하지 않습니다. 지금 댓글을 작성하면 다음과 같은 오류가 발생할 것입니다:
Missing partial blorgh/comments/_comment with {:handlers=>[:erb, :builder], :formats=>[:html], :locale=>[:en, :en]}. Searched in: * "/Users/ryan/Sites/side_projects/blorgh/test/dummy/app/views" * "/Users/ryan/Sites/side_projects/blorgh/app/views"
엔진은 댓글 렌더링에 필요한 partial을 찾을 수 없습니다. Rails는 먼저 애플리케이션의(test/dummy
) app/views
디렉토리를 찾고 그 다음에 엔진의 app/views
디렉토리를 찾습니다. 찾을 수 없으면 이 오류가 발생합니다. 엔진은 Blorgh::Comment
클래스의 모델 객체를 받기 때문에 blorgh/comments/_comment
를 찾아야 합니다.
이 partial은 현재 댓글 텍스트만 렌더링할 것입니다. app/views/blorgh/comments/_comment.html.erb
에 새 파일을 만들고 다음 줄을 넣습니다:
<%= comment_counter + 1 %>. <%= comment.text %>
comment_counter
지역 변수는 <%= render @article.comments %>
가 제공하는 것이며, 반복할 때마다 자동으로 정의되고 증가합니다. 이 예에서는 각 댓글 옆에 작은 번호를 표시하는 데 사용됩니다.
이로써 블로그 엔진의 댓글 기능이 완성되었습니다. 이제 애플리케이션에서 이를 사용할 차례입니다.
애플리케이션에 연결하기
애플리케이션 내에서 엔진을 사용하는 것은 매우 쉽습니다. 이 섹션에서는 애플리케이션에 엔진을 마운트하고 필요한 초기 설정을 수행하는 방법, 그리고 엔진에 기사와 댓글의 소유권을 제공하도록 애플리케이션의 User
클래스에 연결하는 방법을 다룹니다.
엔진 마운트하기
먼저 Gemfile
에 엔진을 지정해야 합니다. 테스트할 애플리케이션이 없다면 엔진 디렉토리 외부에서 rails new
명령을 사용하여 하나를 생성할 수 있습니다:
$ rails new unicorn
일반적으로 Gemfile
에 엔진을 지정하는 것은 일반적인 일상적인 gem과 같은 방식으로 수행됩니다.
gem "devise"
그러나 blorgh
엔진을 로컬 머신에서 개발하고 있기 때문에 Gemfile
에 :path
옵션을 사용해야 합니다:
gem "blorgh", path: "engines/blorgh"
그런 다음 bundle
을 실행하여 gem을 설치합니다.
앞서 설명한 대로 Gemfile
에 gem을 배치하면 Rails가 로드될 때 로드됩니다. 먼저 엔진의 lib/blorgh.rb
를 요구한 다음 엔진의 주요 기능을 정의하는 lib/blorgh/engine.rb
를 요구합니다.
엔진의 기능을 애플리케이션 내에서 사용할 수 있게 하려면 애플리케이션의 config/routes.rb
파일에 마운트해야 합니다:
mount Blorgh::Engine, at: "/blog"
이 줄은 엔진을 /blog
에 마운트합니다. 이렇게 하면 bin/rails server
로 애플리케이션을 실행할 때 http://localhost:3000/blog
에서 엔진에 액세스할 수 있습니다.
참고: Devise와 같은 다른 엔진은 devise_for
와 같은 사용자 지정 헬퍼를 지정하는 방식으로 이를 처리합니다. 이러한 헬퍼는 정확히 같은 작업을 수행하지만 미리 정의된 경로에 엔진의 기능을 마운트하며 이 경로는 사용자 지정이 가능할 수 있습니다.
엔진 설정
엔진에는 blorgh_articles
및 blorgh_comments
테이블에 대한 마이그레이션이 포함되어 있으며, 엔진의 모델이 이 테이블을 올바르게 쿼리할 수 있도록 애플리케이션의 데이터베이스에 이 테이블을 생성해야 합니다. 이 마이그레이션을 애플리케이션으로 복사하려면 애플리케이션의 루트에서 다음 명령을 실행합니다:
$ bin/rails blorgh:install:migrations
여러 엔진의 마이그레이션을 복사해야 하는 경우 railties:install:migrations
를 대신 사용하세요:
$ bin/rails railties:install:migrations
소스 엔진에 대한 마이그레이션 경로를 지정하려면 MIGRATIONS_PATH를 사용할 수 있습니다.
$ bin/rails railties:install:migrations MIGRATIONS_PATH=db_blourgh
여러 데이터베이스가 있는 경우 DATABASE를 지정하여 대상 데이터베이스를 지정할 수도 있습니다.
$ bin/rails railties:install:migrations DATABASE=animals
이 명령을 처음 실행하면 엔진의 모든 마이그레이션이 복사됩니다. 다음에 실행하면 이미 복사된 마이그레이션만 복사됩니다. 이 명령의 첫 번째 실행은 다음과 같은 출력을 생성합니다:
Copied migration [timestamp_1]_create_blorgh_articles.blorgh.rb from blorgh Copied migration [timestamp_2]_create_blorgh_comments.blorgh.rb from blorgh
첫 번째 타임스탬프([timestamp_1]
)는 현재 시간이 되고 두 번째 타임스탬프([timestamp_2]
)는 현재 시간에 1초를 더한 값이 됩니다. 이렇게 하는 이유는 엔진의 마이그레이션이 애플리케이션의 기존 마이그레이션 이후에 실행되도록 하기 위함입니다.
이러한 마이그레이션을 애플리케이션의 컨텍스트에서 실행하려면 단순히 bin/rails db:migrate
를 실행하면 됩니다. http://localhost:3000/blog
에 액세스하면 기사가 비어 있습니다. 이는 애플리케이션 내에 생성된 테이블이 엔진 내에 생성된 것과 다르기 때문입니다. 새로 마운트된 엔진을 가지고 놀아보세요. 엔진만 있을 때와 동일한 것을 발견할 수 있습니다.
특정 엔진의 마이그레이션만 실행하고 싶다면 SCOPE
를 지정하면 됩니다:
$ bin/rails db:migrate SCOPE=blorgh
이는 엔진을 제거하기 전에 엔진의 마이그레이션을 되돌리고 싶은 경우 유용할 수 있습니다. blorgh 엔진의 모든 마이그레이션을 되돌리려면 다음과 같이 실행할 수 있습니다:
$ bin/rails db:migrate SCOPE=blorgh VERSION=0
애플리케이션이 제공하는 클래스 사용하기
애플리케이션이 제공하는 모델 사용하기
엔진이 생성되면 엔진의 구성 요소와 애플리케이션의 구성 요소 간 링크를 제공하기 위해 애플리케이션의 특정 클래스를 사용하고 싶을 수 있습니다. blorgh
엔진의 경우 기사와 댓글에 작성자가 있으면 좋을 것 같습니다.
일반적인 애플리케이션에는 사용자를 나타내는 User
클래스가 있을 수 있습니다. 그러나 애플리케이션에서 이 클네, 계속해서 번역하겠습니다.
일반적인 애플리케이션에는 사용자를 나타내는 User
클래스가 있을 수 있습니다. 그러나 애플리케이션에서 이 클래스를 Person
과 같은 다른 이름으로 호출할 수도 있습니다. 이러한 이유로 엔진은 특정 User
클래스에 대한 연결을 하드코딩해서는 안 됩니다.
이 경우 간단하게 유지하기 위해 애플리케이션에 애플리케이션 사용자를 나타내는 User
클래스가 있다고 가정하겠습니다(이를 구성 가능하게 만드는 방법에 대해서는 나중에 다룰 것입니다). 애플리케이션에서 다음 명령을 사용하여 이 클래스를 생성할 수 있습니다:
$ bin/rails generate model user name:string
bin/rails db:migrate
명령을 실행하여 향후 사용을 위해 users
테이블을 만들어야 합니다.
또한 간단하게 유지하기 위해 기사 폼에 author_name
이라는 새 텍스트 필드를 추가할 것입니다. 사용자는 이 이름을 입력할 수 있습니다. 엔진은 그런 다음 이 이름을 사용하여 새 User
객체를 만들거나 이미 존재하는 객체를 찾을 것입니다. 엔진은 그런 다음 찾거나 생성된 User
객체와 기사를 연결할 것입니다.
먼저 app/views/blorgh/articles/_form.html.erb
엔진 내의 partial에 author_name
텍스트 필드를 추가해야 합니다. 이를 title
필드 위에 추가할 수 있습니다:
<div class="field"> <%= form.label :author_name %><br> <%= form.text_field :author_name %> </div>
다음으로 Blorgh::ArticlesController#article_params
메서드를 업데이트하여 새 폼 매개변수를 허용해야 합니다:
def article_params params.require(:article).permit(:title, :text, :author_name) end
그런 다음 Blorgh::Article
모델에서 author_name
필드를 실제 User
객체로 변환하고 기사가 저장되기 전에 해당 객체를 연결해야 합니다. 또한 이 필드에 대한 setter와 getter 메서드를 정의하는 attr_accessor
가 필요합니다.
이 모든 것을 수행하려면 app/models/blorgh/article.rb
에 attr_accessor
for author_name
, author
연결 및 before_validation
호출을 추가해야 합니다. author
연결은 현재 User
클래스로 하드코딩됩니다.
attr_accessor :author_name belongs_to :author, class_name: "User" before_validation :set_author private def set_author self.author = User.find_or_create_by(name: author_name) end
author
연결의 객체를 User
클래스로 나타냄으로써 엔진과 애플리케이션 간에 링크가 설정됩니다. blorgh_articles
테이블의 레코드와 users
테이블의 레코드를 연결할 방법이 필요합니다. author
라는 연결 이름 때문에 blorgh_articles
테이블에 author_id
열이 추가되어야 합니다.
이 새 열을 생성하려면 엔진 내에서 다음 명령을 실행합니다:
$ bin/rails generate migration add_author_id_to_blorgh_articles author_id:integer
참고: 마이그레이션의 이름과 그 뒤의 열 사양 때문에 Rails는 자동으로 특정 테이블에 열을 추가하려는 것을 알고 마이그레이션에 이를 작성합니다. 더 이상 알려줄 필요가 없습니다.
이 마이그레이션은 애플리케이션에서 실행되어야 합니다. 이를 위해 먼저 다음 명령을 사용하여 복사해야 합니다:
$ bin/rails blorgh:install:migrations
여기서는 단 하나의 마이그레이션만 복사되었음에 주목하세요. 이는 처음 이 명령을 실행했을 때 처음 두 개의 마이그레이션이 이미 복사되었기 때문입니다.
NOTE Migration [timestamp]_create_blorgh_articles.blorgh.rb from blorgh has been skipped. Migration with the same name already exists. NOTE Migration [timestamp]_create_blorgh_comments.blorgh.rb from blorgh has been skipped. Migration with the same name already exists. Copied migration [timestamp]_add_author_id_to_blorgh_articles.blorgh.rb from blorgh
다음 명령을 사용하여 마이그레이션을 실행합니다:
$ bin/rails db:migrate
이제 모든 부분이 제자리에 있으므로 blorgh_articles
테이블의 레코드와 users
테이블의 레코드, 즉 기사의 작성자가 연결됩니다.
마지막으로 작성자 이름이 기사 페이지에 표시되어야 합니다. app/views/blorgh/articles/_article.html.erb
에서 “Title” 출력 위에 다음 코드를 추가합니다:
<p> <strong>Author:</strong> <%= article.author.name %> </p>
애플리케이션이 제공하는 컨트롤러 사용하기
일반적으로 Rails 컨트롤러는 인증 및 세션 변수 액세스와 같은 코드를 공유하므로 기본적으로 ApplicationController
에서 상속됩니다. 그러나 Rails 엔진은 메인 애플리케이션과 독립적으로 실행되도록 설계되어 있으므로 각 엔진에는 범위가 지정된 ApplicationController
가 있습니다. 이 네임스페이스는 코드 충돌을 방지하지만 엔진 컨트롤러는 종종 메인 애플리케이션의 ApplicationController
에 있는 메서드에 액세스해야 합니다. 이에 대한 쉬운 방법은 엔진의 범위가 지정된 ApplicationController
를 메인 애플리케이션의 ApplicationController
에서 상속하도록 변경하는 것입니다. Blorgh 엔진의 경우 app/controllers/blorgh/application_controller.rb
를 다음과 같이 변경하면 됩니다:
module Blorgh class ApplicationController < ::ApplicationController end end
기본적으로 엔진의 컨트롤러는 Blorgh::ApplicationController
에서 상속됩니다. 따라서 이 변경을 수행한 후에는 메인 애플리케이션의 ApplicationController
에 액세스할 수 있습니다. 마치 메인 애플리케이션의 일부인 것처럼 동작합니다.
이 변경에는 엔진이 ApplicationController
를 가진 Rails 애플리케이션에서 실행되어야 한다는 요구 사항이 있습니다.
엔진 구성하기
이 섹션에서는 사용자 클래스를 구성 가능하게 만드는 방법과 엔진에 대한 일반적인 구성 팁을 다룹니다.
애플리케이션에서 구성 설정 지정하기
다음 단계는 애플리케이션 내에서 사용자를 나타내는 클래스를 엔진에 맞춤형으로 만드는 것입니다. 이는 해당 클래스가 항상 User
가 아닐 수 있기 때문입니다(앞서 설명한 바와 같이). 이 구성 설정을 사용자 지정 가능하게 만들기 위해 엔진에 author_class
라는 구성 설정이 있습니다.
이 구성 설정을 정의하려면 Blorgh
모듈 내에 mattr_accessor
를 사용해야 합니다. lib/blorgh.rb
에 다음 줄을 추가합니다:
mattr_accessor :author_class
이 메서드는 attr_accessor
와 cattr_accessor
의 형제와 같이 작동하지만 지정된 이름의 setter와 getter 메서드를 모듈에 제공합니다. 이를 사용하려면 Blorgh.author_class
로 참조해야 합니다.
다음 단계는 Blorgh::Article
모델을 이 새 설정으로 전환하는 것입니다. app/models/blorgh/article.rb
의 belongs_to
연결을 다음과 같이 변경합니다:
belongs_to :author, class_name: Blorgh.author_class
Blorgh::Article
모델의 set_author
메서드도 이 클래스를 사용해야 합니다:
self.author = Blorgh.author_class.constantize.find_or_create_by(name: author_name)
author_class
결과를 계속 constantize
하지 않도록 하려면 lib/blorgh.rb
파일의 Blorgh
모듈 내에서 author_class
getter 메서드를 재정의하여 항상 저장된 값을 constantize
하도록 할 수 있습니다:
def self.author_class @@author_class.constantize end
이렇게 하면 set_author
의 위 코드가 다음과 같이 약간 더 짧고 암시적인 동작이 됩니다:
self.author = Blorgh.author_class.find_or_create_by(name: author_name)
author_class
메서드가 이제 Class
객체를 반환하므로 Blorgh::Article
모델의 belongs_to
정의도 수정해야 합니다:
belongs_to :author, class_name: Blorgh.author_class.to_s
이 구성 설정을 애플리케이션 내에서 설정하려면 초기화기를 사용해야 합니다. 초기화기를 사용하면 애플리케이션이 시작되고 엔진의 모델이 이 구성 설정에 의존할 수 있기 전에 구성이 설정됩니다.
blorgh
엔진이 설치된 애플리케이션의 config/initializers/blorgh.rb
에 새 초기화기를 만들고 다음 내용을 넣습니다:
Blorgh.author_class = "User"
경고: 여기서는 클래스의 String
버전을 사용해야 합니다. 클래스 자체를 사용하면 Rails가 해당 클래스를 로드하려 하고 관련 테이블을 참조하려 할 수 있습니다. 이로 인해 테이블이 아직 존재하지 않는 경우 문제가 발생할 수 있습니다. 따라서 String
을 사용하고 나중에 엔진에서 constantize
를 사용하여 클래스로 변환해야 합니다.
새 기사를 만들어 보세요. 이전과 동일하게 작동하지만 이번에는 config/initializers/blorgh.rb
의 구성 설정을 사용하여 클래스를 알아냅니다.
이제 클래스가 무엇인지에 대한 엄격한 종속성이 없습니다. 엔진에서는 해당 클래스가 find_or_create_by
메서드를 정의하고 기사와 연결될 수 있는 객체를 반환하기만 하면 됩니다. 물론 이 객체에는 참조할 수 있는 식별자가 있어야 합니다.
일반적인 엔진 구성
엔진 내에서는 초기화기, 국제화 또는 기타 구성 옵션과 같은 기능을 사용하고 싶은 경우가 있을 수 있습니다. 좋은 소식은 이러한 기능이 완전히 가능하다는 것입니다. Rails 엔진은 Rails 애플리케이션과 매우 유사한 기능을 공유하기 때문입니다. 사실 Rails 애플리케이션의 기능은 엔진이 제공하는 기능의 상위 집합입니다!
초기화기(엔진이 로드되기 전네, 계속해서 번역하겠습니다.
초기화기(엔진이 로드되기 전에 실행되어야 하는 코드)를 사용하고 싶다면 config/initializers
폴더가 그 장소입니다. 이 디렉토리의 기능은 구성 가이드의 초기화기 섹션에 설명되어 있으며 애플리케이션의 config/initializers
디렉토리와 정확히 동일한 방식으로 작동합니다. 표준 초기화기를 사용하고 싶다면 동일한 방식이 적용됩니다.
로케일의 경우 config/locales
디렉토리에 로케일 파일을 배치하면 됩니다. 애플리케이션에서와 마찬가지로 작동합니다.
엔진 테스트하기
엔진이 생성되면 test/dummy
내에 더미 애플리케이션이 생성됩니다. 이 애플리케이션은 엔진을 테스트하기 위한 마운팅 지점으로 사용됩니다. 이 애플리케이션 내에서 컨트롤러, 모델 또는 뷰를 생성하여 엔진을 테스트할 수 있습니다.
test
디렉토리는 일반적인 Rails 테스트 환경처럼 취급되어야 하며, 단위, 기능 및 통합 테스트를 허용합니다.
기능 테스트
기능 테스트를 작성할 때 고려해야 할 사항은 테스트가 엔진 자체가 아닌 test/dummy
애플리케이션에서 실행된다는 것입니다. 이는 테스트 환경 설정 때문입니다. 엔진은 테스트의 주요 기능, 특히 컨트롤러를 테스트하기 위해 호스트 애플리케이션이 필요합니다. 이는 다음과 같은 일반적인 GET
요청을 컨트롤러의 기능 테스트에서 수행하면 제대로 작동하지 않을 수 있음을 의미합니다:
module Blorgh class FooControllerTest < ActionDispatch::IntegrationTest include Engine.routes.url_helpers def test_index get foos_url # ... end end end
애플리케이션이 엔진의 라우팅을 명시적으로 알려주지 않는 한 이 요청이 제대로 작동하지 않습니다. 이를 위해 설정 코드에서 @routes
인스턴스 변수를 엔진의 경로 집합으로 설정해야 합니다:
module Blorgh class FooControllerTest < ActionDispatch::IntegrationTest include Engine.routes.url_helpers setup do @routes = Engine.routes end def test_index get foos_url # ... end end end
이렇게 하면 애플리케이션에 여전히 GET
요청을 index
액션에 수행하지만 애플리케이션의 경로가 아닌 엔진의 경로를 사용하도록 지시합니다.
이렇게 하면 테스트에서 엔진의 URL 헬퍼가 예상대로 작동합니다.
엔진 기능 향상시키기
이 섹션에서는 메인 Rails 애플리케이션에서 엔진의 MVC 기능을 추가 및/또는 재정의하는 방법을 설명합니다.
모델과 컨트롤러 재정의하기
엔진의 모델과 컨트롤러는 부모 애플리케이션에 의해 재열림어 확장하거나 장식할 수 있습니다.
재정의는 app/overrides
라는 전용 디렉토리에 구성될 수 있으며, 자동 로더에 의해 무시되고 to_prepare
콜백에서 사전 로드됩니다:
# config/application.rb module MyApp class Application < Rails::Application # ... overrides = "#{Rails.root}/app/overrides" Rails.autoloaders.main.ignore(overrides) config.to_prepare do Dir.glob("#{overrides}/**/*_override.rb").sort.each do |override| load override end end end end
class_eval
을 사용하여 기존 클래스 재열기
예를 들어 엔진 모델을 재정의하려면
# Blorgh/app/models/blorgh/article.rb module Blorgh class Article < ApplicationRecord # ... end end
클래스를 재열기하는 파일을 만들면 됩니다:
# MyApp/app/overrides/models/blorgh/article_override.rb Blorgh::Article.class_eval do # ... end
클래스 또는 모듈 키워드를 사용하는 것이 매우 중요합니다. 그렇지 않으면 정의가 메모리에 이미 있기 때문에 잘못 정의될 수 있습니다. class_eval
을 사용하면 클래스를 올바르게 재열 수 있습니다.
ActiveSupport::Concern
을 사용하여 기존 클래스 재열기
Class#class_eval
은 단순한 조정에 좋지만 더 복잡한 클래스 수정의 경우 ActiveSupport::Concern
을 사용하는 것을 고려해 볼 수 있습니다.
ActiveSupport::Concern은 런타임에 상호 종속적인 모듈 및 클래스의 로드 순서를 관리하여 코드를 크게 모듈화할 수 있습니다.
Article#time_since_created
추가 및 Article#summary
재정의:
# MyApp/app/models/blorgh/article.rb class Blorgh::Article < ApplicationRecord include Blorgh::Concerns::Models::Article def time_since_created Time.current - created_at end def summary "#{title} - #{truncate(text)}" end end
# Blorgh/app/models/blorgh/article.rb module Blorgh class Article < ApplicationRecord include Blorgh::Concerns::Models::Article end end
# Blorgh/lib/concerns/models/article.rb module Blorgh::Concerns::Models::Article extend ActiveSupport::Concern # `included do` 블록은 모듈이 포함된 컨텍스트(즉, Blorgh::Article)에서 평가되도록 합니다. # 모듈 자체가 아닙니다. included do attr_accessor :author_name belongs_to :author, class_name: "User" before_validation :set_author private def set_author self.author = User.find_or_create_by(name: author_name) end end def summary "#{title}" end module ClassMethods def some_class_method 'some class method string' end end end
자동 로드 및 엔진
자동 로드 및 상수 재로드에 대한 자세한 내용은 자동 로드 및 상수 재로드 가이드를 확인하세요.
뷰 재정의하기
Rails가 렌더링할 뷰를 찾을 때 먼저 애플리케이션의 app/views
디렉토리를 찾습니다. 여기에서 찾을 수 없는 경우 이 디렉토리를 가진 모든 엔진을 확인합니다.
Blorgh::ArticlesController
의 index 액션에 대한 뷰를 렌더링하라고 요청하면 먼저 애플리케이션의 app/views/blorgh/articles/index.html.erb
를 찾습니다. 찾을 수 없는 경우 엔진 내부를 확인합니다.
단순히 app/views/blorgh/articles/index.html.erb
에 새 파일을 만들어 이 뷰를 재정의할 수 있습니다. 그런 다음 이 뷰가 일반적으로 출력하는 내용을 완전히 변경할 수 있습니다.
이를 시도해 보려면 app/views/blorgh/articles/index.html.erb
에 새 파일을 만들고 다음 내용을 넣으세요:
<h1>Articles</h1> <%= link_to "New Article", new_article_path %> <% @articles.each do |article| %> <h2><%= article.title %></h2> <small>By <%= article.author %></small> <%= simple_format(article.text) %> <hr> <% end %>
라우팅
엔진 내의 라우팅은 기본적으로 애플리케이션과 격리됩니다. 이는 Engine
클래스 내의 isolate_namespace
호출 때문입니다. 이는 애플리케이션과 엔진이 동일한 이름의 라우팅을 가질 수 있지만 충돌하지 않도록 하는 것을 의미합니다.
엔진 내의 라우팅은 Engine
클래스 내의 config/routes.rb
에 그려집니다. 다음과 같이 말이죠:
Blorgh::Engine.routes.draw do resources :articles end
이와 같이 격리된 라우팅을 사용하면 엔진의 라우팅 프록시 메서드를 사용하여 애플리케이션 내에서 엔진 영역에 링크해야 합니다. 일반적인 라우팅 메서드 articles_path
를 사용하면 애플리케이션의 articles_path
로 이동할 수 있습니다.
예를 들어 다음 예제에서는 템플릿이 애플리케이션에서 렌더링되면 애플리케이션의 articles_path
로 이동하고, 엔진에서 렌더링되면 엔진의 articles_path
라우팅 헬퍼 메서드로 이동합니다:
<%= link_to "Blog articles", articles_path %>
엔진의 articles_path
라우팅 헬퍼 메서드를 항상 사용하려면 엔진과 동일한 이름의 라우팅 프록시 메서드를 호출해야 합니다.
<%= link_to "Blog articles", blorgh.articles_path %>
애플리케이션 내에서 엔진을 참조하려면 main_app
헬퍼를 사용하면 됩니다:
<%= link_to "Home", main_app.root_path %>
엔진 내에서 이를 사용하면 항상 애플리케이션의 루트로 이동합니다. main_app
“라우팅 프록시” 메서드 호출을 생략하면 엔진의 루트 또는 애플리케이션의 루트로 이동할 수 있습니다.
엔진에서 렌더링된 템플릿이 애플리케이션의 라우팅 헬퍼 메서드를 사용하려고 하면 정의되지 않은 메서드 호출이 발생할 수 있습니다. 이러한 문제가 발생하면 엔진 내에서 main_app
접두사 없이 애플리케이션의 라우팅 메서드를 호출하려고 하지 않는지 확인하세요.
자산
엔진 내의 자산은 전체 애플리케이션과 동일한 방식으로 작동합니다. Rails::Engine
에서 상속되기 때문에 애플리케이션은 엔진의 app/assets
및 lib/assets
디렉토리에서 자산을 찾습니다.
엔진의 다른 모든 구성 요소와 마찬가지로 자산도 네임스페이스화해야 합니다. 즉, style.css
라는 자산이 있는 경우 app/assets/stylesheets/[engine name]/style.css
에 배치해야 하며, app/assets/stylesheets/style.css
에 배치하면 안 됩니다. 자산이 네임스페이스화되지 않으면 호스트 애플리케이션에 동일한 이름의 자산이 있을 수 있으며, 이 경우 애플리케이션의 자산이 우선하고 엔진의 자산은 무시됩니다.
app/assets/stylesheets/blorgh/style.css
에 자산이 있다고 가정해 보겠습니다. 이 자산을 애플리케이션 내에 포함하려면 stylesheet_link_tag
를 사용하고 엔진 네, 계속해서 번역하겠습니다.
app/assets/stylesheets/blorgh/style.css
에 자산이 있다고 가정해 보겠습니다. 이 자산을 애플리케이션 내에 포함하려면 stylesheet_link_tag
를 사용하고 엔진 내부의 자산인 것처럼 참조하면 됩니다:
<%= stylesheet_link_tag "blorgh/style.css" %>
Asset Pipeline의 require 문을 사용하여 다른 자산에 대한 종속성을 지정할 수도 있습니다:
/*
*= require blorgh/style
*/
정보. Sass나 CoffeeScript와 같은 언어를 사용하려면 엔진의 .gemspec
에 관련 라이브러리를 추가해야 합니다.
별도의 자산 및 사전 컴파일
엔진의 자산이 호스트 애플리케이션에 필요하지 않은 경우도 있습니다. 예를 들어 엔진에 대한 관리 기능을 만들었다고 가정해 보겠습니다. 이 경우 호스트 애플리케이션에서 admin.css
또는 admin.js
를 포함할 필요가 없습니다. 오직 gem의 관리 레이아웃만 이러한 자산을 필요로 합니다. 호스트 앱에 "blorgh/admin.css"
를 포함시키는 것은 적절하지 않습니다. 이러한 상황에서는 이러한 자산을 명시적으로 사전 컴파일 대상으로 정의해야 합니다. 이렇게 하면 bin/rails assets:precompile
이 실행될 때 엔진 자산이 포함됩니다.
engine.rb
에서 사전 컴파일 대상 자산을 정의할 수 있습니다:
initializer "blorgh.assets.precompile" do |app| app.config.assets.precompile += %w( admin.js admin.css ) end
자세한 내용은 자산 파이프라인 가이드를 참조하세요.
기타 Gem 종속성
엔진 내의 gem 종속성은 엔진의 루트 디렉토리에 있는 .gemspec
파일에 지정해야 합니다. 그 이유는 엔진이 gem으로 설치될 수 있기 때문입니다. 종속성을 Gemfile
내에 지정하면 일반적인 gem install
중에는 인식되지 않아 엔진이 제대로 작동하지 않을 수 있습니다.
엔진과 함께 설치되어야 하는 종속성을 지정하려면 엔진의 .gemspec
파일 내 Gem::Specification
블록에 지정하면 됩니다:
s.add_dependency "moo"
애플리케이션의 개발 종속성으로만 설치되어야 하는 종속성을 지정하려면 다음과 같이 하면 됩니다:
s.add_development_dependency "moo"
bundle install
을 실행하면 두 종류의 종속성 모두 설치됩니다. 엔진의 개발 및 테스트에 사용되는 개발 종속성만 설치됩니다.
엔진이 요구될 때 즉시 종속성을 요구하려면 엔진 초기화 전에 이를 요구해야 합니다. 예를 들어:
require "other_engine/engine" require "yet_another_engine/engine" module MyEngine class Engine < ::Rails::Engine end end