Rails에서 뷰 모델: 혼돈을 해결하기 위한 실험

View Models in Rails: An experiment to solve the chaos | A. Christian Toscano

작성자
발행일
2025년 09월 12일

핵심 요약

  • 1 Rails 뷰의 복잡성(비즈니스 로직 침투, N+1 쿼리, 테스트 어려움)을 해결하기 위해 컨트롤러와 뷰 사이의 프리젠테이션 로직을 전담하는 뷰 모델(View Model) 패턴을 소개합니다.
  • 2 뷰 모델은 순수 Ruby 클래스로, 여러 모델과 컨텍스트를 받아 뷰가 필요로 하는 데이터를 준비하고 프리젠테이션 결정을 중앙화하여 뷰를 단순화하고 책임 분리를 명확히 합니다.
  • 3 뷰 모델 도입은 로직 중앙화, 성능 개선, 의미론적 명확성, 쉬운 테스트를 가능하게 하여 복잡한 Rails 애플리케이션의 유지보수성을 크게 향상시키는 효과적인 솔루션입니다.

도입

Rails 애플리케이션의 뷰는 초기에는 단순하지만, 비즈니스 로직 침투, 여러 모델 직접 접근 등으로 빠르게 복잡해져 성능 저하, 로직 분산, 테스트 난이도 증가를 야기합니다. 본 글은 이러한 뷰의 혼란을 해결하기 위한 실험으로, 컨트롤러와 뷰 사이에 위치하여 프리젠테이션 로직과 데이터 준비를 전담하는 뷰 모델(View Model) 패턴 도입을 제안합니다. 이 접근 방식은 뷰를 순수 렌더링 역할에 집중시키고, 애플리케이션의 구조적 명확성과 견고성을 높이는 것을 목표로 합니다.

Rails 뷰의 문제점

기존 뷰는 다음과 같은 문제를 야기합니다. * 다중 모델/변수 접근: 뷰에서 여러 모델에 직접 접근하여 데이터 흐름 추적이 어렵습니다. * 비즈니스 로직 침투: 뷰에 if current_user.subscription.active? 같은 비즈니스 로직이 혼재되어 책임 분리를 위반합니다. * 성능 문제: user.articles.count와 같은 N+1 쿼리를 유발하여 성능을 저하시킵니다. * 로직 분산: 동일한 비즈니스 규칙이 여러 뷰에 중복 구현되어 변경 시 일관성 유지가 어렵습니다. * 테스트 어려움: 뷰 로직은 격리 테스트가 어렵고 통합 테스트에 의존하게 됩니다.

뷰 모델(View Model) 소개

뷰 모델은 컨트롤러와 뷰 사이에 위치하는 순수 Ruby 클래스입니다. 모델과 컨텍스트를 받아 뷰가 호출할 메서드를 제공하며, 프리젠테이션 결정을 처리하고 해당 요청의 유일한 DTO 역할을 합니다.

컨트롤러 및 뷰 사용 예시: 컨트롤러에서 UserProfileViewModel 인스턴스를 생성하여 데이터를 주입하고, 뷰에서는 @vm.display_name이나 @vm.show_premium_content처럼 뷰 모델의 메서드를 호출하여 렌더링합니다. 이로써 뷰는 프리젠테이션에만 집중합니다.

뷰 모델의 장점

  • 로직 중앙화 및 단방향 흐름: 모든 프리젠테이션 로직이 컨트롤러에 집중되며, 뷰 모델을 통해 뷰에 전달되는 명확한 단방향 흐름을 확립합니다.
  • 성능 향상: 필요한 데이터를 미리 로드(eager loading)하여 N+1 쿼리를 방지합니다.
  • 의미론적 명확성: 뷰는 구현 세부사항 없이 의도를 명확히 전달하는 메서드를 호출합니다.
  • 쉬운 테스트: 순수 Ruby 객체이므로 단위 테스트가 용이하며, 컨트롤러 요청 스펙으로 데이터 구성을 검증할 수 있습니다.

대안

  • Presenters/Decorators (Draper): 단일 모델의 단순 프리젠테이션 로직에 적합합니다.
  • View Components (ViewComponent): 재사용 가능한 UI 요소에 유용합니다.
  • Cells: UI의 특정 부분에 대한 미니 컨트롤러로, UI와 로직을 강하게 연결합니다.

결론

뷰 모델은 Rails 뷰의 복잡성을 관리하고 애플리케이션 유지보수성을 높이는 강력한 도구입니다. 여러 모델에 접근하고 복잡한 프리젠테이션 로직을 포함하는 애플리케이션에서 특히 효과적이며, 로직 중앙화, 성능 개선, 테스트 용이성 등의 이점을 제공합니다. 뷰 모델은 기존 Rails 뷰 패턴의 완벽한 대안은 아니지만, 가장 복잡한 뷰부터 점진적으로 도입하여 개선해 나갈 수 있습니다. 이를 통해 뷰를 순수 렌더링 역할에 집중시키고, 더 깨끗하고 성능이 뛰어나며 유지보수하기 쉬운 Rails 애플리케이션 구축에 기여할 것입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!