[RoR 학습] 9장 장바구니 기능

루비온 레일스 학습 사용 교재: 『레일스와 함께하는 애자일 웹 개발』

지금까지 레일스에 기본적인 폴더 구성, 레이아웃, 테스트에 대해서 점진적으로 개발하면서 맛을 봤다. 이제 매장마다 기능이 하나, 둘씩 추가되면서 상점 애플리케이션 다운 모습을 찾아간다. 빠르게 따라가본다.

9장은 장바구니 기능을 추가한다. 현재까지 가지고 있는 데이터는 상품인 Product 밖에 없었다. 따라서 여기서는 장바구니인 Cart와 장바구니에 포함된 상품인 Line_item을 더한다. 교재를 따라가면서 잠깐 잊어버릴 뻔 했는데 Rails는 ORM을 사용한다. 따라서 장바구니의 해당하는 테이블 스키마나 품목에 대하 테이블 스키마를 어떻게 설계할까 생각하지 않는다. 직관적으로 필요한 객체인 장바구니와 품목을 떠올렸다면 이 객체 에 해당하는 모델을 생성하면 된다.

이렇게 장바구니와 품목 그리고 상품 사이의 모델을 생성한 후에 모델간에 관계를 설정해 준다. 모델 간의 관계는 간단히 다음 그림과 같다.

Object 관계장바구니 안에는 여러 개의 품목들이 포함될 수 있고 마찬가지로 하나의 상품이 복수의 품목으로 존재할 수 있기 때문에 위와 같은 관계가 성립된다. 자연스럽게 품목은 장바구니와 상품 모델에 종속되고 레일스에는 belong_to로 표현한다. 관계를 표현하는 코드는 아래와 같이 모델 폴더 안에 각 모델에 해당하는 파일에 넣어두면 된다.

장바구니 모델 코드에 포함된 “dependent” 조건은 장바구니가 삭제 될 때에 연결된 품목까지 함께 삭제한다는 의미이다.

상품 모델에는 조금 더 복잡한 내용이 포함된다. “before_destory”는 훅메서드라고 하여 레일스에서 자동으로 객체가 사용되는 흐름 과정에 따라 해당하는 단계에서 자동으로 실행시켜 주는 메소드이다. 여기서는 “before_destory” 즉 상품 객체가 삭제 될 때에 뒤에 따라오는 메서드를 실행하게 한다. 이어지는 메서드는 상품과 연결된 메서드가 있는지 확인한다. 만약 참이면 상품 객체는 정상적으로 삭제되겠지만 품목이 하나라도 있다면 거짓이 반환되어 상품은 삭제될 수 없다.

모델을 생성하고 관계를 설정했으므로 장바구니에 상품을 입력할 수 있도록 페이지에서 장바구니에 넣기(Add to Cart) 버튼을 넣고 메서드를 구현한다. 버튼은 “button_to” 메서드를 사용한다. 이 메서드는 폼을 생성해서 알아서 버튼까지 멋지게 생성해 준다. 8장에서 작업한 index.html에 한 줄만 추가하면 된다.

버튼 입력 상품의 아이디를 매개변수로 넘겨주고 있음을 코드에서 확인한다. 이 한 줄짜리 코드가 자동으로 다음과 같이 늘어난다.

button_to 메서드 html 코드

다음 작업은 button_to 메서드를 통해서 전달되는 상품객체를 처리하는 코드를 품목의 컨트롤러에서 작업해줘야 한다. 품목에서는 장바구니가 기존에 있는지 없는지를 확인하여 없으면 새로 생성하고 여기에 품목을 하나 만들어서 넣어준다.

하단의 respond_to ~ 이하의 내용들은 line_item의 스캐폴드 생성시 자동으로 작성된 코드다. 장바구니에 품목이 제대로 들어갔는지 여부에 따른 성공 및 에러처리 하는 부분이다. 교재에서 자세한 내용은 뒤로 미룬다. 다만 8~9라인은 성공적으로 품목이 장바구니에 들어갈 경우 출력할 문자열과 이동할 페이지를 설정한 것으로 교재를 따라 변경한다.

2번 라인에서 현재 카트가 있는지 없는지를 확인하기 위해서 “current_cart”라는 메서드를 사용했다. 이 메서드는 레일스가 제공해주는 것이 아니라 직접 작성을 해야 한다. 카트의 식별은 세션을 활용하는 자세한 내용은 뒷장으로 미루고 있다. 해당 코드는 아래와 같다.

품목의 컨트롤러를 변경하였기 때문에 테스트 코드도 변경이 필요하다. 레일스 4에서는 테스트 폴더의 구조와 3.2와 다르다는 것을 한번 더 확인한다. 1

마지막이다. 장바구니에 상품을 넣었을 때 어떤 상품들이 있는지 출력해 줘야 한다. 자동으로 생성된 show.html.erb를 수정한다.

 소스코드는 Github에 있으며 9장 코드는 “chapter-9″의 태그버전으로 확인 가능하다.

 

Notes:

  1. 3.2에서는 test/functional/ 밑에 있고 4.0에서는 test/controllers/ 밑에 있다.