Rails 라우팅 — URL을 콘트롤러로 연결하는 규칙
Rails 라우팅 — URL을 콘트롤러로 연결하는 규칙
브라우저에 /products/1 같은 주소를 입력하면 Rails는 어떤 콘트롤러의 어떤 액션이 실행될지를 결정해야 해요. 이 결정을 내려주는 규칙 모음이 바로 **라우팅(routing)**이에요. 라우터는 퍼즐의 조각들을 이어주는 역할을 하는데, 들어온 요청의 URL을 보고 매칭되는 라우트를 찾아 해당 콘트롤러 액션을 호출하고, 그 결과를 조립해서 응답으로 되돌려줘요. 라우팅을 이해하면 "어떤 URL이 어떤 코드로 이어지는가"가 머릿속에 자연스럽게 그려져요.
본문
라우팅의 목적
Rails의 라우터는 두 가지 일을 한 번에 처리해요. 하나는 들어오는 요청을 액션으로 연결하는 것이고, 다른 하나는 URL 경로를 만들어내는 헬퍼 메서드를 생성하는 것이에요. 이 덕분에 링크를 만들 때 URL을 하드코딩하는 대신 products_path처럼 라우트가 만들어 준 헬퍼를 쓰면 되죠.
리소스 기반 라우팅
가장 많이 쓰는 방식은 resources로 RESTful 리소스를 선언하는 거예요.
Rails.application.routes.draw do
resources :products
end
이 한 줄로 일곱 개의 표준 라우트가 만들어져요. HTTP 동사와 URL, 액션의 대응 관계를 정리하면 이렇게 되죠.
| HTTP 동사 | 경로 | 액션 | 용도 |
|---|---|---|---|
| GET | /products |
index |
목록 표시 |
| POST | /products |
create |
새 레코드 저장 |
| GET | /products/new |
new |
생성 폼 표시 |
| GET | /products/:id |
show |
단건 표시 |
| PATCH/PUT | /products/:id |
update |
기존 레코드 갱신 |
| GET | /products/:id/edit |
edit |
수정 폼 표시 |
| DELETE | /products/:id |
destroy |
레코드 삭제 |
:id처럼 콜론으로 시작하는 부분을 동적 세그먼트라고 불러요. 요청이 들어오면 여기에 실제 값이 채워져서 콘트롤러의 params로 전달돼요.
단일 리소스
하나의 객체만 다루는 경우에는 resource(단수형)를 쓸 수 있어요. 이 경우 index 라우트와 :id를 포함한 라우트가 만들어지지 않아요.
resource :geocoder
resolve("Geocoder") { [:geocoder] }
추가 라우트
리소스에 액션이 기본 일곱 개를 넘어서 추가될 때가 있어요. 예를 들어 상품을 검색하는 기능을 추가한다면 이렇게 작성해요.
resources :products do
get :search, on: :collection
get :preview, on: :member
end
on: :collection은 URL에 :id가 없는 컬렉션 라우트(/products/search)를 만들고, on: :member는 :id가 붙는 멤버 라우트(/products/:id/preview)를 만들어요. 여러 개를 묶으려면 collection do ... end 블록을 쓰는 편이 깔끔해요.
중첩 리소스
리소스가 소속 관계를 가질 때는 중첩으로 표현해요. 예를 들어 기사(articles)가 여러 댓글(comments)을 가진다면 이렇게 선언하죠.
resources :articles do
resources :comments
end
이렇게 하면 /articles/1/comments 같은 경로가 유효해져요. 다만 중첩이 깊어지면 URL이 길어지고 라우트가 복잡해지므로, 일반적으로는 중첩을 한 단계로 유지하는 걸 권장해요.
블록 없는 리소스 라우팅
resources에 리소스 여러 개를 한 번에 넘기면 동일한 액션 집합을 한꺼번에 만들 수 있어요.
resources :photos, :books, :videos
지금은 블록 안에서 다시 resources를 쓰는 대신, 같은 레벨로 필요한 리소스들을 나열하는 방식을 더 권장한답니다.
매칭 순서
Rails는 라우트를 파일에 적힌 순서대로 위에서 아래로 매칭해요. 맨 처음 매칭된 라우트가 실행되고 나머지는 무시되죠. 그래서 제네럴한 라우트보다 구체적인 라우트를 먼저 적어야 해요. 예를 들어 /products/:id처럼 :id를 받는 라우트 뒤에 /products/new를 두면, new가 :id로 잡혀버릴 수 있으니 조심해야 해요.
라우트 확인
설정한 라우트의 실제 형태를 확인하고 싶다면 콘솔에서 이 명령을 쓰면 돼요.
bin/rails routes
이 명령은 모든 라우트의 동사, 경로, 액션, 헬퍼를 한눈에 보여줘요. -g 옵션으로 특정 리소스만 걸러낼 수도 있어요.
bin/rails routes -g products
더 알아보기 (Learn more)
- 공식 문서 Rails Routing from the Outside In
- Action Controller 개요에서 라우트가 호출한 액션이 어떻게 요청을 처리하는지
- Getting Started with Rails로 라우팅부터 뷰까지 한 흐름으로 익히기