1. 조건문 기반 렌더링의 문제점
일반적으로 상속 구조를 가진 모델(예: Property 아래의 SingleUnitProperty, MultiUnitProperty)을 처리할 때, 개발자들은 뷰 파일 내에서 if property.is_a?(SingleUnitProperty)와 같은 타입 체크 조건문을 사용하곤 합니다. 하지만 모델의 종류가 늘어날수록 이 조건문은 길어지고 관리가 불가능한 수준(Gnarly)에 이르게 됩니다. 이는 개방-폐쇄 원칙(OCP)을 위반하며 새로운 타입이 추가될 때마다 기존 뷰 코드를 수정해야 하는 유지보수 비용 증가의 주요 원인이 됩니다.
2. Rails의 컨벤션을 활용한 자동 렌더링
Rails는 모델 객체 자체를 render 메서드에 전달할 때 매우 지능적으로 동작합니다. render @property를 호출하면 Rails는 내부적으로 해당 객체의 클래스 이름을 확인하고, 약속된 경로에서 파셜을 찾습니다.
* 동작 방식: SingleUnitProperty 객체라면 Rails는 app/views/single_unit_properties/_single_unit_property.html.erb 파일을 자동으로 탐색합니다.
* 장점: 뷰 코드에서 복잡한 로직이 사라지고 단 한 줄의 코드로 타입별 최적화된 UI를 출력할 수 있습니다. 이는 코드의 가독성을 높일 뿐만 아니라 Rails의 철학에 부합하는 깔끔한 코드를 만들어줍니다.
3. STI와 파셜 구조의 최적화
단일 테이블 상속(STI)을 사용하면 데이터베이스는 하나의 테이블(properties)을 사용하지만, Rails 레벨에서는 각기 다른 클래스로 취급됩니다. 이를 효과적으로 렌더링하기 위해 다음과 같은 구조를 권장합니다.
* 공통 속성 처리: 모든 프로퍼티가 공유하는 속성은 베이스 클래스의 뷰나 레이아웃에서 처리합니다.
* 타입별 고유 속성 분리: 각 모델 이름에 맞춘 전용 디렉토리를 생성하고 그 안에 파셜을 배치합니다. 예를 들어 주차 공간은 single_unit_properties에, 유닛 수는 multi_unit_properties에 각각 분리하여 관리합니다.
* 응집도 향상: 이렇게 분리된 파셜은 특정 모델의 요구사항에만 집중할 수 있어 코드의 응집도를 높여줍니다.
4. 문자열 보간을 이용한 동적 파셜 경로 지정
표준적인 객체 렌더링 외에 edit 폼이나 특정 목적의 파셜을 동적으로 불러와야 할 때가 있습니다. 이때는 ActiveModel::Name 객체의 기능을 활용할 수 있습니다.
* 핵심 메서드: property.model_name.plural을 사용하면 해당 모델의 복수형 이름을 문자열로 얻을 수 있습니다. 이는 디렉토리 경로를 동적으로 생성하는 데 유용합니다.
* 구현 예시: render "#{property.model_name.plural}/form", property: property와 같이 작성하여 각 모델 전용 디렉토리에 있는 _form.html.erb를 동적으로 로드할 수 있습니다.
* 변수 표준화: 파셜 내부에서 사용하는 지역 변수 이름을 single_unit_property 대신 property와 같이 일반적인 명칭으로 통일하면 여러 타입에서 파셜을 재사용하기가 훨씬 수월해집니다.
5. 동적 렌더링 사용 시의 트레이드오프
동적 파셜 렌더링은 강력하지만 몇 가지 주의사항이 존재합니다. 특히 erb-lint와 같은 도구에서는 동적 경로 사용을 지양하라는 규칙을 제안하기도 합니다.
* 런타임 에러 위험: 존재하지 않는 파셜 경로가 동적으로 생성될 경우 런타임에 Missing Partial 에러가 발생할 수 있습니다.
* 정적 분석의 한계: 코드를 실행해보기 전에는 어떤 파셜이 실제 사용되는지 파악하기 어려워 대규모 프로젝트에서 디버깅이 까다로울 수 있습니다.
* 대안 및 권장사항: Rails의 최신 기능인 엄격한 로컬 변수(Strict Locals) 정의를 활용하거나, 모델 내에서 to_partial_path를 오버라이드하는 대신 뷰에서 명시적으로 보간법을 사용하여 유연성을 확보하는 것이 좋습니다.