Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

Ruby on Rails 7.1: 스트릭트 로컬(Strict Locals) 완벽 정복하기

Rails의 파셜(partial)은 오랫동안 사용되어 왔지만, 백킹 객체 구조가 없는 단순한 ERB 코드 조각에 불과하기 때문에 다루기 번거로운 면이 있었습니다.

최근에는 ViewComponent와 Phlex 같은 라이브러리들이 템플릿에 더 많은 의미론적 구조를 부여하여 뷰 계층을 개선하려고 시도하고 있습니다. 이들은 훌륭한 라이브러리이며, 저 역시 거의 모든 프로젝트에서 ViewComponent를 손꼽아 사용합니다. 그럼에도 불구하고 소박한 Rails 파셜은 여전히 많은 사용 사례에서 충분히 잘 작동한다고 생각합니다.

Rails 팀은 항상 더 나은 기능을 제공하기 위해 노력합니다. 그래서 이번 글에서는 Rails 7.1에서 새롭게 도입된 기능인 스트릭트 로컬(strict locals)을 살펴보겠습니다!

Rails 파셜과 로컬 변수

Rails 파셜에는 임의의 로컬 변수를 전달할 수 있으며, 전달된 변수들은 별도의 선언 없이 곧바로 사용할 수 있습니다.


하지만 이 방식은 이상적이지 않습니다. 마크업 블록이 큰 경우 해당 파셜이 어떤 변수를 받는지 파악하기 어렵기 때문입니다. 게다가 변수가 동적으로 생성되다 보니, 존재하지 않는 변수는 nil을 반환하는 대신 에러를 발생시킵니다.

예를 들어 위 파셜에서 icon이 선택 사항이라고 가정해 보겠습니다.


이를 다음과 같이 렌더링하면:


ActionView::Template::Error가 발생하며, 메시지는 undefined local variable or method 'icon' for #<ActionView::Base:0x00000000023078>입니다.

icon이 선택 사항이라는 사실은 코드를 읽는 사람에게도 명확하지 않습니다. Rails 7.1 이전에는 주입된 모든 로컬 변수를 담고 있는 local_assigns 해시를 확인하는 것이 해결책이었습니다.


이제 icon 변수가 항상 설정되기 때문에 위의 에러는 사라집니다.

Rails 7.1은 스트릭트 로컬(strict locals)이라는 개념으로 파셜의 로컬 변수가 지닌 이러한 한계를 해결하고자 합니다.

Rails의 스트릭트 로컬이란?

Rails 7.1부터는 파셜 상단에 매직 코멘트(magic comment)를 작성하여 해당 파셜이 받는 로컬 변수와 각각의 기본값을 정의할 수 있습니다.


Rails는 이 코멘트를 파싱하여 정의된 변수들을 파셜에 설정합니다. 이제 어떤 변수를 받는지, 기본값은 무엇인지 코드를 읽는 사람에게 아주 명확하게 드러납니다.

파셜은 여전히 위와 같이 렌더링됩니다. 그렇다면 호출부에서 title 변수를 빼고 실행하면 어떻게 될까요?


missing local: :title이라는 메시지와 함께 ArgumentError가 발생합니다. 예전보다 훨씬 설명적인 에러 메시지입니다!

스트릭트 로컬을 언제 사용해야 할까?

스트릭트 로컬은 다소 까다로울 수 있어서, 특히 레거시 애플리케이션에서는 항상 좋은 선택이라고 할 수 없습니다.

스트릭트 로컬이 빛을 발하는 사용 사례를 살펴보겠습니다. 사용자 정보를 카드 형태로 보여주는 파셜이 있는데, 마지막 로그인 시간은 관리자에게만 노출된다고 가정해 봅시다.


이 파셜은 여러 변수를 받으면서 선택적인 변수도 하나 있으므로, 스트릭트 로컬의 완벽한 적용 대상입니다. 파일에 다음 매직 코멘트를 추가하면 훨씬 쉽게 훑어볼 수 있습니다.


반면 모델과 연관된 파셜(예: posts/_post.html.erb)의 경우, 그런 파셜이 단일 post 변수를 받는다는 것은 비교적 자명합니다. 이런 경우에는 굳이 스트릭트 로컬을 사용할 필요가 없다고 생각합니다.

스트릭트 로컬의 함정들

주의해야 할 함정이 몇 가지 있으며, 그래서 저는 스트릭트 로컬을 무조건 전면적으로 적용할 것을 권장하지 않습니다.

컬렉션 암시적 렌더링

컬렉션을 암시적으로 렌더링할 때:


Rails는 post 변수 외에 두 개의 변수를 추가로 주입하여 _post 파셜에 전달합니다. Rails 7.1.2 이전에는 에러를 막기 위해 이 변수들을 직접 정의해야 했습니다.


이 문제는 Rails 7.1.2에서 수정되었으며, 이제 이 변수들은 선택 사항입니다(필요할 때를 대비해 존재를 알아두면 유용합니다)!

ActionCable을 통한 브로드캐스팅

ActiveRecord 콜백에서 ActionCable을 통해 파셜을 브로드캐스팅할 때:


Rails가 내부적으로 사용하기 때문에 기본값이 nilrequest_id 로컬 변수를 반드시 지정해야 합니다.


그렇지 않으면 콜백이 트리거될 때 에러가 발생합니다.

이것으로 간단한 투어를 마치겠습니다!

기억해야 할 몇 가지 사항

기존 파셜에 스트릭트 로컬을 추가하는 것은 해당 파일 기준으로 전부 아니면 전무(all-or-nothing) 방식입니다. 변수를 발견할 때마다 매직 코멘트에 점진적으로 추가할 수는 없습니다. 위의 함정들에서 보았듯이, 매직 코멘트에 선언해야 하는 모든 변수를 파악하는 것 자체가 까다로울 수 있습니다.

스트릭트 로컬을 사용하면 코드를 훨씬 쉽게 이해할 수 있다는 점을 고려하면, 새 애플리케이션에서는 폭넓게 사용할 가치가 충분하다고 생각합니다(레거시 애플리케이션에는 점진적으로 소급 적용하는 방식을 추천합니다).

레거시 애플리케이션에서는 스트릭트 로컬을 추가하는 파셜들이 테스트 스위트에서 커버되고 있는지 확인하는 것이 중요합니다. 하나라도 누락되면 예외가 발생하므로, 변경 사항을 배포하기 전에 모든 사용 사례를 테스트했는지 반드시 확인해야 합니다.

저는 매직 코멘트 방식의 큰 팬은 아니지만(코멘트는 기능을 가져서는 안 된다고 믿기 때문입니다), 스트릭트 로컬은 Rails에 훌륭한 추가 기능이라고 생각합니다. 파셜에 로컬 변수를 할당하는 일은 늘 번거로웠는데, 확실히 편리해졌습니다. 다만 함정들만 조심하세요!

마무리

이번 글에서는 Rails 7.1의 스트릭트 로컬을 간단히 살펴보았습니다. 파셜과 로컬 변수의 동작 방식을 확인한 후, 스트릭트 로컬을 언제 사용하면 좋은지 그리고 주의해야 할 함정들을 알아보았습니다.

즐거운 코딩 되세요!

P.S. Ruby Magic 포스트가 발행되는 즉시 읽고 싶으시다면 Ruby Magic 뉴스레터를 구독하고 어떤 글도 놓치지 마세요!

Ruby on Rails 7.1: 스트릭트 로컬(Strict Locals) 완벽 정복하기

Ayush Newatia

게스트 작성자 Ayush는 프리랜서 Ruby 및 Rails 개발자입니다. 『The Rails and Hotwire Codex』의 저자이며 Bridgetown 코어 팀의 일원이기도 합니다. 또한 프라이버시 중심의 메일링 리스트 앱인 Scattergun을 운영하고 있습니다.

Ayush Newatia의 모든 글 보기