InfoGrab DocsInfoGrab Docs

GitLab Cells 개발 가이드라인

요약

Cells는 서로 다른 조직을 물리적으로 분리된 GitLab 인스턴스가 담당하도록 하는 새 아키텍처입니다. Cells는 GitLab.com 에만 적용할 계획입니다. 기능을 만들거나 수정하는 모든 개발자는 다음 원칙을 따라야 합니다.

개요#

Cells는 서로 다른 조직을 물리적으로 분리된 GitLab 인스턴스가 담당하도록 하는 새 아키텍처입니다. 각 인스턴스를 cell 이라고 부릅니다. 이 아키텍처의 목표와 배경은 Cells 목표 페이지를 참고합니다. 아키텍처 전반의 개요는 설계 문서를 참고합니다.

Cells는 GitLab.com 에만 적용할 계획입니다. GitLab Self-Managed와 GitLab Dedicated는 단일 cell로 동작합니다.

Cells 개발 원칙#

기능을 만들거나 수정하는 모든 개발자는 다음 원칙을 따라야 합니다.

아래 원칙은 모두 이미 자동화되어 있지만, 예외 사례와 레거시 사례는 남아 있습니다.

컴퓨팅 범위를 단일 조직으로 제한#

웹·API 요청과 Sidekiq 워커는 단일 조직 아래에서 실행되어야 합니다. 조직 간에 걸친 컴퓨팅은 가능한 한 조직 범위로 전환합니다. 조직 간에 걸친 Sidekiq job은 해당 job 이 반복 실행되는 cron job 이면서 멱등할 때만 허용됩니다. 자세한 내용은 Sidekiq의 Cells 호환성을 참고합니다.

요청은 올바른 cell로 라우팅 가능해야 함#

cell 외부에서 오는 요청을 받는 모든 cell 로컬 서비스는 요청이 속한 조직을 기준으로 올바른 cell로 라우팅될 수 있어야 합니다. 그다음 대상 cell의 cell 로컬 서비스가 해당 요청을 처리합니다.

이는 웹, API, Git은 물론 서비스별 프로토콜(예: KAS 나 컨테이너 레지스트리)을 포함한 모든 요청 유형과 프로토콜에 적용됩니다.

조직 데이터 소유권을 명확하게 유지#

조직 데이터는 다른 cell로 이전할 수 있어야 합니다. 이는 상태를 가지는 모든 cell 로컬 서비스에 적용됩니다.

GitLab Rails 모놀리스 데이터베이스에서는 스키마만 봐도 데이터 소유권이 분명해야 합니다. 모든 고객 데이터 테이블은 샤딩 키를 통해 조직까지 추적할 수 있는 경로를 가져야 합니다.

고객 데이터를 저장하는 모든 새 모델은 각 행이 단일 조직에 귀속되도록 샤딩 키를 정의해야 합니다. 고객 데이터가 아닌 데이터(고객 조직에 속하지 않는 데이터)는 스키마 분류에서 cell 로컬로 표시해야 합니다. cell 로컬이라는 것은 해당 행이 cell을 벗어나지 않는다는 뜻입니다.

새 테이블을 설계하거나 기존 테이블을 확장할 때는 각 행의 소유권이 모호하지 않은지 확인합니다. 소유권이 모호하면 이후 cell 이전이 막힙니다.

조직 외부에 새 고객 소유 리소스를 추가하지 않음#

조직 외부에 존재하는 새 고객 소유 리소스를 도입하지 않습니다. 모든 고객 데이터는 조직 안에 속해야 합니다. 조직 외부에 존재하는 리소스는 조직이 다른 cell로 이동할 때 이전할 수 없습니다.

조직은 cell에 격리됨#

조직은 본질적으로 하나의 cell에 격리됩니다. 한 조직의 모든 데이터와 컴퓨팅은 단일 cell에 존재합니다. 조직 데이터에 대한 cell 간 접근은 지원하지 않습니다.

조직 간 격리는 조직의 선택#

같은 cell에 있는 조직 사이의 격리는 조직이 선택합니다. 이는 조직 간 상호 작용이 이미 존재할 수 있는 레거시 cell(기존 GitLab.com 인스턴스)의 기존 조직에서 특히 중요합니다.

조직 간 격리를 제공하는 제어 장치는 해당 조직이 격리를 선택했는지 여부를 고려해야 합니다. 같은 cell에 있는 모든 조직이 서로 격리되어 있다고 가정하지 않습니다.

사용 가능한 Cells / Organization 스키마#

Cells 및 Organization과 관련된 스키마는 다음과 같습니다.

스키마 설명
gitlab_main(지원 중단) Cells 아키텍처를 구축하기 위해 gitlab_main_org로 대체되고 있습니다.
gitlab_main_org main: 데이터베이스에서 Organization에 속하는 모든 테이블에 사용합니다. 예: projects, groups
gitlab_main_cell_setting main: 데이터베이스에서 cell 설정과 관련된 모든 테이블입니다. 예: application_settings. 이러한 cell 로컬 테이블은 gitlab_main_org 나 gitlab_main_user 테이블을 강한 외래 키로 참조할 수 있지만, 조직 테이블의 외래 키가 이들을 참조해서는 안 됩니다.
gitlab_main_cell_local main: 데이터베이스에서 cell 마다 다른 기능과 관련된 테이블입니다. 예: zoekt_nodes, shards. 이러한 cell 로컬 테이블은 gitlab_main_org 나 gitlab_main_user 테이블을 강한 외래 키로 참조할 수 있지만, 조직 테이블의 외래 키가 이들을 참조해서는 안 됩니다.
gitlab_ci ci: 데이터베이스에서 Organization에 속하는 모든 테이블에 사용합니다. 예: ci_pipelines, ci_builds
gitlab_ci_cell_local ci: 데이터베이스에서 cell 마다 다른 기능과 관련된 테이블입니다. 예: instance_type_ci_runners, ci_cost_settings. 이러한 cell 로컬 테이블은 gitlab_main_org 나 gitlab_main_user 테이블을 강한 외래 키로 참조할 수 있지만, 조직 테이블의 외래 키가 이들을 참조해서는 안 됩니다.
gitlab_main_user users, emails 등 사용자 관련 테이블 전체를 위한 스키마입니다. 대부분의 사용자 기능은 조직 수준이므로 그 경우에는 gitlab_main_org를 사용해야 합니다(예: 이슈에 댓글 달기). 조직 수준이 아닌 사용자 기능에는 이 스키마를 사용합니다. 이 스키마의 테이블은 엄격히 한 사용자에게 속해야 합니다.
gitlab_shared_org 여러 데이터베이스에 걸친 데이터를 담고 샤딩을 위해 organization_id를 가지는 테이블용 스키마입니다. 이러한 테이블은 Gitlab::Database::SharedModel을 상속합니다. 분해된 데이터베이스 전반에서 행이 고유한 기본 키를 갖도록, 이 스키마의 테이블은 자동 증가 정수 스키마를 사용할 수 없습니다. 대신 복합 키나 UUID 기본 키를 사용합니다.
gitlab_shared_cell_local 샤딩이 필요 없고 여러 데이터베이스에 걸쳐 존재하는 cell 로컬 공유 테이블용 스키마입니다. 예: loose_foreign_keys_deleted_records. 이러한 테이블도 Gitlab::Database::SharedModel을 상속합니다.
gitlab_sec_cell_local sec: 데이터베이스에서 샤딩 키가 없는 cell 로컬 비고객 참조 데이터를 담는 테이블용입니다. 예를 들어 멀웨어와 패키지 메타데이터 권고가 여기에 해당합니다. 이러한 행은 조직에 속하지 않고, cell 안의 모든 조직에 대해 동일하며, cell 마다 복제됩니다. 이 스키마의 테이블은 SecApplicationRecord를 사용합니다.

대부분의 테이블에는 샤딩 키를 정의해야 합니다.

기존 테이블이 어떻게 분류되어 있는지는 이 대시보드에서 확인할 수 있습니다.

스키마를 할당한 뒤 다음 이유 중 하나 이상으로 머지 리퀘스트 파이프라인이 실패할 수 있으며, 링크된 지침을 따라 해결할 수 있습니다.

새 스키마 생성#

기능은 기본적으로 Organization 범위로 한정되어야 하므로, 스키마도 기본적으로 샤딩 키를 요구해야 합니다.

# db/gitlab_schemas/gitlab_ci.yaml
require_sharding_key: true
sharding_root_tables:
  - projects
  - namespaces
  - organizations

require_sharding_key를 true로 설정하면 해당 스키마에 할당된 테이블은 sharding_key를 설정해야 합니다. 또한 이 스키마의 테이블에서 샤딩 키로 사용할 수 있는 sharding_root_tables 목록도 구성해야 합니다.

데이터베이스 시퀀스#

GitLab은 모든 cell에 걸쳐 데이터베이스 시퀀스의 고유성을 보장합니다. 따라서 대부분의 테이블에서 id 칼럼은 고유합니다.

기술 구현과 아키텍처 결정은 다음을 참고합니다.

고유 제약 조건#

데이터가 고유해야 한다면 Organization, Group, Project, User 단위로 고유하도록 범위를 정해야 합니다. 각기 독립된 데이터베이스를 가진 여러 cell 이 존재하므로, 더 이상 UNIQUE 제약 조건에 의존할 수 없습니다.

방법은 두 가지입니다.

  1. 인덱스에 포함된 칼럼 중 하나로 sharding_key가 들어가도록 인덱스 범위를 정합니다.
  2. 속성이 모든 조직에 걸쳐 전역적으로 고유해야 하는 드문 경우에는 Claim 서비스를 사용합니다.

Claim 서비스#

Rails에서 claim 서비스를 사용하는 방법은 다음을 참고합니다. cell에 속성 클레임하기

정적 데이터#

문제: 데이터베이스 테이블을 정적 데이터 저장에 사용하는 경우입니다. 그런데 기본 키가 자동 증가 시퀀스를 사용하므로 정적이지 않습니다. 즉 기본 키가 전역적으로 일관되지 않습니다.

이렇게 일관되지 않은 기본 키를 참조하면 cell과 조직 사이에서 참조가 충돌하므로 문제가 생깁니다.

예시: 특정 Cell의 plans 테이블에는 다음 데이터가 있습니다.

 id |             name             |              title
----+------------------------------+----------------------------------
  1 | default                      | Default
  2 | bronze                       | Bronze
  3 | silver                       | Silver
  5 | gold                         | Gold
  7 | ultimate_trial               | Ultimate Trial
  8 | premium_trial                | Premium Trial
  9 | opensource                   | Opensource
  4 | premium                      | Premium
  6 | ultimate                     | Ultimate
 10 | ultimate_trial_paid_customer | Ultimate Trial for Paid Customer
(10 rows)

다른 cell에서는 같은 name에 대해 plans 테이블의 id가 다릅니다.

 id |             name             |            title
----+------------------------------+------------------------------
  1 | default                      | Default
  2 | bronze                       | Bronze
  3 | silver                       | Silver
  4 | premium                      | Premium
  5 | gold                         | Gold
  6 | ultimate                     | Ultimate
  7 | ultimate_trial               | Ultimate Trial
  8 | ultimate_trial_paid_customer | Ultimate Trial Paid Customer
  9 | premium_trial                | Premium Trial
 10 | opensource                   | Opensource

이 plans.id 칼럼은 gitlab_subscriptions 테이블의 hosted_plan_id 칼럼에서 참조로 사용됩니다.

해결책: 데이터베이스 시퀀스가 아니라 전역적으로 고유한 참조를 사용합니다. 가능하다면 데이터베이스를 쓰는 대신 정적 데이터를 애플리케이션 코드에 하드코딩합니다.

이 경우 plans 테이블을 삭제하고 고정 모델로 대체할 수 있습니다 (자세한 내용은 구성 가능한 상태 설계 문서에서 확인할 수 있습니다).

class Plan
  include ActiveRecord::FixedItemsModel::Model

  ITEMS = [
    {:id=>1, :name=>"default", :title=>"Default"},
    {:id=>2, :name=>"bronze", :title=>"Bronze"},
    {:id=>3, :name=>"silver", :title=>"Silver"},
    {:id=>4, :name=>"premium", :title=>"Premium"},
    {:id=>5, :name=>"gold", :title=>"Gold"},
    {:id=>6, :name=>"ultimate", :title=>"Ultimate"},
    {:id=>7, :name=>"ultimate_trial", :title=>"Ultimate Trial"},
    {:id=>8, :name=>"ultimate_trial_paid_customer", :title=>"Ultimate Trial Paid Customer"},
    {:id=>9, :name=>"premium_trial", :title=>"Premium Trial"},
    {:id=>10, :name=>"opensource", :title=>"Opensource"}
  ]

  attribute :name, :string
  attribute :title, :string
end

모델 유효성 검사를 사용할 수 있고, all, where, find_by, find 같은 ActiveRecord 방식의 메서드도 쓸 수 있습니다.

Plan.find(4)
Plan.find_by(name: 'premium')
Plan.where(name: 'gold').first

hosted_plan_id 칼럼도 고정 모델의 id 값을 참조하도록 갱신됩니다.

다른 모델과의 연관 관계도 저장할 수 있습니다. 예를 들면 다음과 같습니다.

class CurrentStatus < ApplicationRecord
  belongs_to_fixed_items :system_defined_status, fixed_items_class: WorkItems::Statuses::SystemDefined::Status
end

고정 항목 모델 구현에 대한 전체 가이드는 고정 항목 모델을 참고합니다.

정적 데이터를 하드코딩한 예는 다음과 같습니다.

기타 주제#

라우팅은 HTTP Router를 참고합니다. 클러스터 전역 서비스는 Topology Service를 참고합니다.

GitLab Cells 개발 가이드라인

GitLab v19.4
원문 보기

요약

Cells는 서로 다른 조직을 물리적으로 분리된 GitLab 인스턴스가 담당하도록 하는 새 아키텍처입니다. Cells는 GitLab.com 에만 적용할 계획입니다. 기능을 만들거나 수정하는 모든 개발자는 다음 원칙을 따라야 합니다.

개요#

Cells는 서로 다른 조직을 물리적으로 분리된 GitLab 인스턴스가 담당하도록 하는 새 아키텍처입니다. 각 인스턴스를 cell 이라고 부릅니다. 이 아키텍처의 목표와 배경은 Cells 목표 페이지를 참고합니다. 아키텍처 전반의 개요는 설계 문서를 참고합니다.

Cells는 GitLab.com 에만 적용할 계획입니다. GitLab Self-Managed와 GitLab Dedicated는 단일 cell로 동작합니다.

Cells 개발 원칙#

기능을 만들거나 수정하는 모든 개발자는 다음 원칙을 따라야 합니다.

아래 원칙은 모두 이미 자동화되어 있지만, 예외 사례와 레거시 사례는 남아 있습니다.

컴퓨팅 범위를 단일 조직으로 제한#

웹·API 요청과 Sidekiq 워커는 단일 조직 아래에서 실행되어야 합니다. 조직 간에 걸친 컴퓨팅은 가능한 한 조직 범위로 전환합니다. 조직 간에 걸친 Sidekiq job은 해당 job 이 반복 실행되는 cron job 이면서 멱등할 때만 허용됩니다. 자세한 내용은 Sidekiq의 Cells 호환성을 참고합니다.

요청은 올바른 cell로 라우팅 가능해야 함#

cell 외부에서 오는 요청을 받는 모든 cell 로컬 서비스는 요청이 속한 조직을 기준으로 올바른 cell로 라우팅될 수 있어야 합니다. 그다음 대상 cell의 cell 로컬 서비스가 해당 요청을 처리합니다.

이는 웹, API, Git은 물론 서비스별 프로토콜(예: KAS 나 컨테이너 레지스트리)을 포함한 모든 요청 유형과 프로토콜에 적용됩니다.

조직 데이터 소유권을 명확하게 유지#

조직 데이터는 다른 cell로 이전할 수 있어야 합니다. 이는 상태를 가지는 모든 cell 로컬 서비스에 적용됩니다.

GitLab Rails 모놀리스 데이터베이스에서는 스키마만 봐도 데이터 소유권이 분명해야 합니다. 모든 고객 데이터 테이블은 샤딩 키를 통해 조직까지 추적할 수 있는 경로를 가져야 합니다.

고객 데이터를 저장하는 모든 새 모델은 각 행이 단일 조직에 귀속되도록 샤딩 키를 정의해야 합니다. 고객 데이터가 아닌 데이터(고객 조직에 속하지 않는 데이터)는 스키마 분류에서 cell 로컬로 표시해야 합니다. cell 로컬이라는 것은 해당 행이 cell을 벗어나지 않는다는 뜻입니다.

새 테이블을 설계하거나 기존 테이블을 확장할 때는 각 행의 소유권이 모호하지 않은지 확인합니다. 소유권이 모호하면 이후 cell 이전이 막힙니다.

조직 외부에 새 고객 소유 리소스를 추가하지 않음#

조직 외부에 존재하는 새 고객 소유 리소스를 도입하지 않습니다. 모든 고객 데이터는 조직 안에 속해야 합니다. 조직 외부에 존재하는 리소스는 조직이 다른 cell로 이동할 때 이전할 수 없습니다.

조직은 cell에 격리됨#

조직은 본질적으로 하나의 cell에 격리됩니다. 한 조직의 모든 데이터와 컴퓨팅은 단일 cell에 존재합니다. 조직 데이터에 대한 cell 간 접근은 지원하지 않습니다.

조직 간 격리는 조직의 선택#

같은 cell에 있는 조직 사이의 격리는 조직이 선택합니다. 이는 조직 간 상호 작용이 이미 존재할 수 있는 레거시 cell(기존 GitLab.com 인스턴스)의 기존 조직에서 특히 중요합니다.

조직 간 격리를 제공하는 제어 장치는 해당 조직이 격리를 선택했는지 여부를 고려해야 합니다. 같은 cell에 있는 모든 조직이 서로 격리되어 있다고 가정하지 않습니다.

사용 가능한 Cells / Organization 스키마#

Cells 및 Organization과 관련된 스키마는 다음과 같습니다.

스키마 설명
gitlab_main(지원 중단) Cells 아키텍처를 구축하기 위해 gitlab_main_org로 대체되고 있습니다.
gitlab_main_org main: 데이터베이스에서 Organization에 속하는 모든 테이블에 사용합니다. 예: projects, groups
gitlab_main_cell_setting main: 데이터베이스에서 cell 설정과 관련된 모든 테이블입니다. 예: application_settings. 이러한 cell 로컬 테이블은 gitlab_main_org 나 gitlab_main_user 테이블을 강한 외래 키로 참조할 수 있지만, 조직 테이블의 외래 키가 이들을 참조해서는 안 됩니다.
gitlab_main_cell_local main: 데이터베이스에서 cell 마다 다른 기능과 관련된 테이블입니다. 예: zoekt_nodes, shards. 이러한 cell 로컬 테이블은 gitlab_main_org 나 gitlab_main_user 테이블을 강한 외래 키로 참조할 수 있지만, 조직 테이블의 외래 키가 이들을 참조해서는 안 됩니다.
gitlab_ci ci: 데이터베이스에서 Organization에 속하는 모든 테이블에 사용합니다. 예: ci_pipelines, ci_builds
gitlab_ci_cell_local ci: 데이터베이스에서 cell 마다 다른 기능과 관련된 테이블입니다. 예: instance_type_ci_runners, ci_cost_settings. 이러한 cell 로컬 테이블은 gitlab_main_org 나 gitlab_main_user 테이블을 강한 외래 키로 참조할 수 있지만, 조직 테이블의 외래 키가 이들을 참조해서는 안 됩니다.
gitlab_main_user users, emails 등 사용자 관련 테이블 전체를 위한 스키마입니다. 대부분의 사용자 기능은 조직 수준이므로 그 경우에는 gitlab_main_org를 사용해야 합니다(예: 이슈에 댓글 달기). 조직 수준이 아닌 사용자 기능에는 이 스키마를 사용합니다. 이 스키마의 테이블은 엄격히 한 사용자에게 속해야 합니다.
gitlab_shared_org 여러 데이터베이스에 걸친 데이터를 담고 샤딩을 위해 organization_id를 가지는 테이블용 스키마입니다. 이러한 테이블은 Gitlab::Database::SharedModel을 상속합니다. 분해된 데이터베이스 전반에서 행이 고유한 기본 키를 갖도록, 이 스키마의 테이블은 자동 증가 정수 스키마를 사용할 수 없습니다. 대신 복합 키나 UUID 기본 키를 사용합니다.
gitlab_shared_cell_local 샤딩이 필요 없고 여러 데이터베이스에 걸쳐 존재하는 cell 로컬 공유 테이블용 스키마입니다. 예: loose_foreign_keys_deleted_records. 이러한 테이블도 Gitlab::Database::SharedModel을 상속합니다.
gitlab_sec_cell_local sec: 데이터베이스에서 샤딩 키가 없는 cell 로컬 비고객 참조 데이터를 담는 테이블용입니다. 예를 들어 멀웨어와 패키지 메타데이터 권고가 여기에 해당합니다. 이러한 행은 조직에 속하지 않고, cell 안의 모든 조직에 대해 동일하며, cell 마다 복제됩니다. 이 스키마의 테이블은 SecApplicationRecord를 사용합니다.

대부분의 테이블에는 샤딩 키를 정의해야 합니다.

기존 테이블이 어떻게 분류되어 있는지는 이 대시보드에서 확인할 수 있습니다.

스키마를 할당한 뒤 다음 이유 중 하나 이상으로 머지 리퀘스트 파이프라인이 실패할 수 있으며, 링크된 지침을 따라 해결할 수 있습니다.

새 스키마 생성#

기능은 기본적으로 Organization 범위로 한정되어야 하므로, 스키마도 기본적으로 샤딩 키를 요구해야 합니다.

# db/gitlab_schemas/gitlab_ci.yaml
require_sharding_key: true
sharding_root_tables:
  - projects
  - namespaces
  - organizations

require_sharding_key를 true로 설정하면 해당 스키마에 할당된 테이블은 sharding_key를 설정해야 합니다. 또한 이 스키마의 테이블에서 샤딩 키로 사용할 수 있는 sharding_root_tables 목록도 구성해야 합니다.

데이터베이스 시퀀스#

GitLab은 모든 cell에 걸쳐 데이터베이스 시퀀스의 고유성을 보장합니다. 따라서 대부분의 테이블에서 id 칼럼은 고유합니다.

기술 구현과 아키텍처 결정은 다음을 참고합니다.

고유 제약 조건#

데이터가 고유해야 한다면 Organization, Group, Project, User 단위로 고유하도록 범위를 정해야 합니다. 각기 독립된 데이터베이스를 가진 여러 cell 이 존재하므로, 더 이상 UNIQUE 제약 조건에 의존할 수 없습니다.

방법은 두 가지입니다.

  1. 인덱스에 포함된 칼럼 중 하나로 sharding_key가 들어가도록 인덱스 범위를 정합니다.
  2. 속성이 모든 조직에 걸쳐 전역적으로 고유해야 하는 드문 경우에는 Claim 서비스를 사용합니다.

Claim 서비스#

Rails에서 claim 서비스를 사용하는 방법은 다음을 참고합니다. cell에 속성 클레임하기

정적 데이터#

문제: 데이터베이스 테이블을 정적 데이터 저장에 사용하는 경우입니다. 그런데 기본 키가 자동 증가 시퀀스를 사용하므로 정적이지 않습니다. 즉 기본 키가 전역적으로 일관되지 않습니다.

이렇게 일관되지 않은 기본 키를 참조하면 cell과 조직 사이에서 참조가 충돌하므로 문제가 생깁니다.

예시: 특정 Cell의 plans 테이블에는 다음 데이터가 있습니다.

 id |             name             |              title
----+------------------------------+----------------------------------
  1 | default                      | Default
  2 | bronze                       | Bronze
  3 | silver                       | Silver
  5 | gold                         | Gold
  7 | ultimate_trial               | Ultimate Trial
  8 | premium_trial                | Premium Trial
  9 | opensource                   | Opensource
  4 | premium                      | Premium
  6 | ultimate                     | Ultimate
 10 | ultimate_trial_paid_customer | Ultimate Trial for Paid Customer
(10 rows)

다른 cell에서는 같은 name에 대해 plans 테이블의 id가 다릅니다.

 id |             name             |            title
----+------------------------------+------------------------------
  1 | default                      | Default
  2 | bronze                       | Bronze
  3 | silver                       | Silver
  4 | premium                      | Premium
  5 | gold                         | Gold
  6 | ultimate                     | Ultimate
  7 | ultimate_trial               | Ultimate Trial
  8 | ultimate_trial_paid_customer | Ultimate Trial Paid Customer
  9 | premium_trial                | Premium Trial
 10 | opensource                   | Opensource

이 plans.id 칼럼은 gitlab_subscriptions 테이블의 hosted_plan_id 칼럼에서 참조로 사용됩니다.

해결책: 데이터베이스 시퀀스가 아니라 전역적으로 고유한 참조를 사용합니다. 가능하다면 데이터베이스를 쓰는 대신 정적 데이터를 애플리케이션 코드에 하드코딩합니다.

이 경우 plans 테이블을 삭제하고 고정 모델로 대체할 수 있습니다 (자세한 내용은 구성 가능한 상태 설계 문서에서 확인할 수 있습니다).

class Plan
  include ActiveRecord::FixedItemsModel::Model

  ITEMS = [
    {:id=>1, :name=>"default", :title=>"Default"},
    {:id=>2, :name=>"bronze", :title=>"Bronze"},
    {:id=>3, :name=>"silver", :title=>"Silver"},
    {:id=>4, :name=>"premium", :title=>"Premium"},
    {:id=>5, :name=>"gold", :title=>"Gold"},
    {:id=>6, :name=>"ultimate", :title=>"Ultimate"},
    {:id=>7, :name=>"ultimate_trial", :title=>"Ultimate Trial"},
    {:id=>8, :name=>"ultimate_trial_paid_customer", :title=>"Ultimate Trial Paid Customer"},
    {:id=>9, :name=>"premium_trial", :title=>"Premium Trial"},
    {:id=>10, :name=>"opensource", :title=>"Opensource"}
  ]

  attribute :name, :string
  attribute :title, :string
end

모델 유효성 검사를 사용할 수 있고, all, where, find_by, find 같은 ActiveRecord 방식의 메서드도 쓸 수 있습니다.

Plan.find(4)
Plan.find_by(name: 'premium')
Plan.where(name: 'gold').first

hosted_plan_id 칼럼도 고정 모델의 id 값을 참조하도록 갱신됩니다.

다른 모델과의 연관 관계도 저장할 수 있습니다. 예를 들면 다음과 같습니다.

class CurrentStatus < ApplicationRecord
  belongs_to_fixed_items :system_defined_status, fixed_items_class: WorkItems::Statuses::SystemDefined::Status
end

고정 항목 모델 구현에 대한 전체 가이드는 고정 항목 모델을 참고합니다.

정적 데이터를 하드코딩한 예는 다음과 같습니다.

기타 주제#

라우팅은 HTTP Router를 참고합니다. 클러스터 전역 서비스는 Topology Service를 참고합니다.