Rails ID 모델의 간략한 역사
-
초기 Rails:
id라는 단일 정수 컬럼을 모든 테이블의 기본 키로 사용했으며, 이는 자동 증가하고 라우팅, 폼 바인딩, 연관 관계의 핵심 역할을 했습니다. 대부분의 CRUD 애플리케이션에는 효과적이었으나,invoice_id + line_number또는tenant_id + user_id와 같은 도메인 중심의 복합 식별자가 필요한 경우 문제가 발생했습니다. -
composite_primary_keysGem: Rails가 복합 식별자를 기본적으로 지원하지 않음에 따라,composite_primary_keysgem이 등장하여 이 간극을 메웠습니다. 이 gem은 복합 키의 필요성을 입증했지만, Rails 자체는 단일id정책을 고수했습니다.
Rails 6 및 7의 변화
-
UUID 기본 키:
id: :uuid옵션을 통해 기본 키를 비숫자형으로 선언할 수 있게 되었습니다. -
커스텀 기본 키 이름:
self.primary_key = :iso_code와 같이 기본 키 이름을 사용자 정의할 수 있게 되어, ID가 기계 생성된 값이 아닌 의미 있는 값일 수 있음을 인정했습니다. 그러나 여전히 기본 키는 단일 스칼라 값으로 예상되었습니다.
Rails 8의 결정적인 변화
- ActiveRecord의 CPK 수용: Rails 8은 ActiveRecord가
id=및 파라미터 직렬화를 통해 복합 기본 키를 수용할 수 있도록 하는 핵심적인 아키텍처 변경을 도입했습니다. 이제 ID를 튜플로 정의할 수 있습니다.- 예시:
create_table :users, id: false do |t| t.primary_key [:tenant_id, :user_id]및class User < ApplicationRecord; self.primary_keys = :tenant_id, :user_id; end와 같이 모델과 DB에 복합 키를 정의할 수 있습니다. User.find(["acme", "john_doe"])와 같이 복합 ID를 사용하여 레코드를 찾을 수 있으며,user.id는["acme", "john_doe"]를 반환합니다.
- 예시:
- 합리적인 라우팅:
user.to_param이"acme:john_doe"와 같이 인코딩되고,GET /users/acme:john_doe와 같은 URL을 통해User.find(params[:id])로 복합 ID를 자동으로 디코딩하여 조회할 수 있게 되었습니다.
Rails 8 네이티브 CPK의 강점 및 한계
-
강점: 다중 컬럼 기본 키 정의,
id=를 통한 ID 처리,to_param인코딩 및 파싱, 컨트롤러에서의 파라미터 재구성,find및exists?작업에서의 복합 ID 사용 등 ID 처리에 일관성을 제공합니다. -
한계: 단일 PK를 예상하는 연관 관계는 변경되지 않았으며, 깊게 중첩된 조인 테이블, 다형적 연관 관계, ActiveRecord 쿼리 헬퍼 등은 여전히 보수적으로 작동합니다. Rails 8은 마법 같은 CPK 프레임워크가 아닌, 견고한 네이티브 ID 기반을 제공하는 데 중점을 둡니다.
composite_primary_keys Gem에서 네이티브 Rails로의 마이그레이션 전략
-
데이터베이스에서 ID를 실제화: 대리(surrogate) 정수 키 대신
t.primary_key [:customer_id, :service_code]와 같이 데이터베이스 수준에서 복합 기본 키를 정의합니다. -
모델로 ID 이동:
self.primary_keys = :customer_id, :service_code를 설정하고,find_by_identity와 같은 사용자 정의 헬퍼를 제거합니다. -
컨트롤러에서 파라미터 ID 활용:
params[:customer]및params[:service]를 개별적으로 사용하는 대신,@subscription = Subscription.find(params[:id])를 사용하여 Rails가 인코딩된 형식을 자동으로 해석하도록 합니다. -
Gem 의미론 점진적 폐지: ID 배열을 일급 객체로 취급하거나 추가적인 조인 구문, 사용자 정의 파인더 API 등 gem이 도입했던 패턴들을 점진적으로 제거합니다.
네이티브 지원의 충분성 및 Gem의 필요성
-
네이티브 지원으로 충분한 경우: 2~3개 컬럼 키, 얕은 연관 관계, 스키마 소유, 다형적 CPK가 필요 없는 경우, ID가 비즈니스 의미를 전달하는 경우 등 대부분의 현대적인 사용 사례를 커버합니다.
-
Gem이 여전히 정당화되는 경우: Oracle/DB2 마이그레이션과 같은 레거시 엔터프라이즈 시나리오, 다차원 이력 키, 5개 이상의 컬럼 ID, 복합 외래 키를 사용하는 다대다 연관 관계 등 복잡한 도메인에서는 여전히 gem이 유용합니다.
Rails 8 호환성 참고
- 2025년 12월 현재
composite_primary_keysgem은 Rails 8을 지원하지 않습니다. 따라서 Rails 8로 업그레이드할 팀은 네이티브 CPK 지원이 요구 사항에 부합하는지 평가하고, 필요한 경우 네이티브 지원으로 마이그레이션하는 것을 고려해야 합니다.