이 글의 핵심은 Rails의 표준 렌더링을 추상화하는 ComponentHelper입니다. 이 헬퍼는 컴포넌트 이름, 로컬 변수, 선택적 블록을 받아, 블록 유무나 컬렉션 여부에 따라 렌더링 전략(레이아웃, 컬렉션, 부분 템플릿)을 결정합니다. 모든 컴포넌트는 app/views/components/ 디렉토리에 위치합니다.
컴포넌트 구현 기법
-
명시적 로컬 변수 (Explicit Locals): Rails 7.2 기능으로,
<%# locals: (user:, css: user.avatar_css) %>처럼 필요한 변수를 명확히 정의하여 인터페이스를 분명히 합니다.component "avatar", user: User.first.decorate와 같이 사용하며 컬렉션 렌더링도 지원합니다. -
콘텐츠 블록 (Content Blocks):
yield를 사용하여 컴포넌트 내부에 콘텐츠를 삽입합니다.section이나breadcrumbs처럼 특정 레이아웃으로 콘텐츠를 감쌀 때 유용하며,component("breadcrumbs", items: [...]) { "Here" }와 같이 블록을 전달합니다. -
데코레이터 (Decorators): 뷰 로직을 모델에서 분리하기 위해
User::Decorator와 같이SimpleDelegator를 상속받아avatar_css같은 뷰 전용 메서드를 정의합니다. 이를 통해 모델은 비즈니스 로직에, 데코레이터는 뷰 로직에 집중합니다. -
클래스 기반 컴포넌트 (Class-based Components): 복잡한 컴포넌트는
BadgeComponent와 같은 전용 Ruby 클래스를 생성하여 로직을 캡슐화합니다. 이 클래스는 컴포넌트의 상태와 행위를 관리하며, 뷰 템플릿은<%= tag.span badge.name, class: badge.css %>처럼 클래스 인스턴스의 메서드를 호출하여 HTML을 렌더링합니다. 이는 ViewComponent와 유사하며 테스트 용이성과 유지보수성을 향상시킵니다.
이러한 접근 방식들을 통해 외부 Gem 없이도 Rails 애플리케이션에서 체계적이고 확장 가능한 UI 컴포넌트 시스템을 구축할 수 있습니다.