저자는 delegated_type
의 현재 구조가 몇 가지 도메인 모델링 문제를 내포하고 있다고 설명합니다. 가장 큰 문제점은 Message
나 Comment
와 같은 내부 타입이 Entry
와 같은 외부 타입 없이는 독립적으로 존재할 수 없음에도 불구하고, 코드 상에서는 이러한 제약이 명확히 드러나지 않는다는 점입니다. 이는 개발자가 내부 타입을 독립적인 최상위 모델로 오인하게 만들 수 있습니다. 저자는 이러한 내부 타입들을 Entry::Message
및 Entry::Comment
와 같이 외부 타입의 네임스페이스 내에 두어 실제 도메인 모델링을 반영해야 한다고 주장합니다. 그러나 현재 delegated_type
은 이러한 네임스페이스를 사용할 경우 entry_comment
와 같은 어색한 접두사 메서드를 생성하는 문제가 있습니다.
이에 대한 개선 방안으로 저자는 다음과 같은 제안을 합니다:
- 명시적 제약 조건 추가: 내부 타입이 외부 타입 없이는 존재할 수 없음을 명확히 하기 위해
has_one :entry, as: :entryable, touch: true, required: true
와 같이required: true
옵션을 추가하고,delegated_type
에는inverse_of: :entry, dependent: :destroy
를 수동으로 할당해야 한다고 제안합니다. - 네이밍 컨벤션 개선:
entryable
과 같은-able
접미사 사용에 대한 불만을 표하며, 이는 잘못된 네이밍의 신호라고 지적합니다. 대신delegate
와 같이 기능의 본질을 더 잘 나타내는 이름을 사용할 것을 제안합니다. 예를 들어,delegated_type :delegate, types: %w[Message Comment], dependent: :destroy
와 같이 변경할 수 있습니다. - 추상 부모 클래스 도입 및 네임스페이스 활용:
ActiveSupport::Concern
모듈을 사용하는 대신, 내부 타입들이 상속받을 추상 부모 클래스인Entry::Delegate
를 도입할 것을 제안합니다.Entry::Delegate
는self.abstract_class = true
를 설정하고has_one :entry, as: :delegate, touch: true, required: true
를 포함하여,Message
나Comment
같은 내부 타입들이 이를 상속받도록 합니다. 이는Entry
네임스페이스가 자신의 위임된 타입 정의를 소유하게 하여 불필요한 보일러플레이트를 줄이고, 애플리케이션 내의 여러delegated_type
패턴에 일관성을 부여합니다. 또한,delegate_type
컬럼 이름이delegate_type
으로 명명되어 패턴의 일관성을 강화합니다. - 네임스페이스 지원 강화:
delegated_type
이 각 타입에 대해 메서드를 생성할 때,Entry::Message
와 같은 네임스페이스 접두사를 자동으로 제거하여 생성된 메서드 이름이 불필요한 접두사를 가지지 않도록 수정하는 방안을 제시합니다. 이를 통해app/models/entry
디렉토리에서 위임된 타입들을 직접 찾을 수 있게 되어 코드 탐색이 용이해집니다. - 명칭 재고: 저자는
delegated_type
이라는 이름이 기능의 핵심을 충분히 전달하지 못한다고 판단하여,composed_with_delegate
와 같은 대안적인 명칭을 제안하며, 이는Entry
가 내부의 가변적인 타입들과 구성된다는 점을 강조합니다. - 렌더링 개선:
Entry
모델에render_in
메서드를 정의하여render entry
와 같이 호출할 때delegate
타입에 따라_message.html.erb
또는_comment.html.erb
와 같은 적절한 부분 템플릿을 자동으로 렌더링하도록 개선하는 방안을 제시합니다. 이는 뷰 레이어에서delegated_type
을 다루는 방식을 간소화합니다.