제 1장 시작부터 배포까지

Ruby on Rails 튜토리얼에 어서오세요! 이 책은 'Ruby on Rails를 통해 웹 프로그래밍을 배울 때 어디부터 시작하면 좋을까요?'하는 질문에 대답하기 위해 쓰여졌습니다. 이 책을 덮을 때 즈음에는 여러분이 원하는 웹어플리케이션을 프로그래밍하고 배포하기 위한 대부분의 지식을 습득할 수 있을 것입니다. 또한 Rails 프레임워크에 관련된 좀 더 심화된 주제를 다루고 있는 책, 블로그, 스크린캐스트를 이해할 수 있는 능력을 갖추게 될 것입니다. Ruby on Rails 튜토리얼에선 Rails 4를 사용합니다. 따라서 이 튜토리얼을 통해 학습한 내용은 Rails 최신버전에서 그대로 사용할 수 있습니다. (Ruby on Rails 튜토리얼의 최신버전에 대해서는 이 책이 공개되어 있는 http://railstutorial.org를 참조해주세요. 이 문서를 책으로 읽고 계신 분은 Rails Tutorial 웹사이트에서 최신판을 확인해주세요.)

(이 튜토리얼은 현재 Rails 4.0을 대상으로 하고 있습니다만, 정식 개정판은 아닙니다. Rails 4.0의 변경사항들이 책을 새로 쓸 정도로 크지는 않다고 판단했기 때문입니다. Rails를 처음 시작하기 위한 튜토리얼로서 Rails3.2와 Rails 4.0의 차이는 크지 않습니다. 물론 아래 박스 1.1에 열거했듯이 작은 변경사항들이 다수 있습니다만, 이 튜토리얼에서 다룰 중요한 변경사항은 7.3.2절에서 다룰 보안에 관련된 Strong Parameters 정도입니다. Rails에 더욱 커다란 변화가 생기면 Rails 튜토리얼의 다음판을 새로 쓸 생각입니다.만약 다음판을 쓰게 된다면 Turbolinks, Russian doll caching, feature specs를 비롯해 RSpec에 관련된 부분이 추가될 겁니다.

이 책의 목표은 Rails의 사용법을 설명하는 데 있지 않습니다. Rails를 사용한 Web 프로그래밍 전반, 즉 World Wide Web용 어플리케이션 프로그래밍에 관련된 기술을 습득하고 단련시키는 걸 목표로 합니다. 따라서 Ruby on Rails 뿐만 아니라 HTML, CSS, 데이터베이스, 버전 관리, 테스트, 배포를 하기 위한 기술 전반에 대해서 이야기합니다. 이러한 목표를 달성하기 위해 Ruby on Rails 튜토리얼에서는 통합적인 관점에서 문제에 접근합니다. 튜토리얼을 통해 실제로 작동하는 예제 어플리케이션을 바닥에서부터 만들어 나가면서 Rails를 익혀나가게 될 것입니다. Derek Sivers가 서문에서 이야기한 대로 이 책은 일관되고 선형적으로 구성되어 있으며, 독자들이 처음부터 마지막까지 순서대로 읽을 것을 전제로 하고 있습니다. 기술서적을 술술 넘겨보거나 발췌독에 익숙한 분들에게는 이 책의 선형적인 구성을 따라오는데 약간의 노력이 필요할 지도 모릅니다. 하지만 꼭 시도해보시기 바랍니다. Ruby on Rails 튜토리얼을 TV 게임에 비유해보죠. 여러분은 주인공이고 한 장 한 장 넘어가면서 Rails 프로그래머로 레벨 업을 해 나갑니다. (연습 문제는 레벨 업을 위한 중간 보스라고 할 수 있죠.)

제 1장에서는 Rails 프로그래밍을 위한 소프트웨어를 인스톨하고 개발 환경(1.2)을 갖추어 본격적인 Ruby on Rails 프로그래밍을 준비합니다. 이어서 첫 Rails 어플리케이션 first_app을 만듭니다. Rails 튜토리얼에선 프로그래밍에 있어 베스트 프랙티스를 중시하고, 또 중시하고 있습니다. 튜토리얼 전반에 걸쳐 Git를 사용하며, 이번 예제에서도 Rails 프로젝트를 생성하고 프로젝트를 곧 바로 Git(1.3) 저장소에 넣어 버전관리를 합니다. 믿으실진 모르겠지만 심지어 여기에서 만든 어플리케이션을 production 환경(1.4)으로 배포(deploy)해서 인터넷에서 접속할 수 있도록 합니다.

제 2장에선 Rails 어플리케이션의 기본적인 구조와 새로운 프로젝트를 만드는 법을 배웁니다. 실제 작동하는 어플리케이션을 간단히 만들어 보기 위해 scaffold(박스 1.1)의 코드 자동 생성 기능을 사용해 데모 어플리케이션(demo_app)을 만듭니다. scaffold로 자동 생성된 코드는 지저분하고 복잡합니다. 따라서 제 2장에선 주로 URI( URL이라고도 불립니다)를 통해 어플리케이션이 소통하는 법을 알아봅니다.

나머지 부분에서는 샘플 어플리케이션(sample_app)을 만듭니다. 이 어플리케이션은 TDD(테스트 주도 개발)로 개발을 진행하며 제 3장에서는 정적 페이지와 동적 콘텐츠를 조금 추가합니다. 제 4장에서는 간략히 Rails를 구성하고 있는 Ruby 언어에 대해서 배웁니다. 제 5장부터는 다시 돌아와 제 9장까지 레이아웃, 유저 모델과 유저 등록 및 인증을 비롯한 샘플 어플리케이션의 기반을 다집니다. 마지막으로 제 10장제 11장에서는 마이크로 블로그 기능과 소셜 기능을 구현해 실제로 사용할 수 있는 사이트를 완성합니다.

최종적으로 완성된 어플리케이션은 한 때 Rails로 만들어졌던 어떤 소셜 마이클로 블로그 사이트와 매우 흡사합니다. Rails 튜토리얼에서는 이 샘플 어플리케이션을 위주로 프로그래밍을 진행해나가지만 이후에 어떤 웹 어플리케이션을 만들더라도 활용할 수 있는 기초를 같이 다져나갑니다.

1.1시작하며

2004년에 처음 등장한 이래 Ruby on Rails는 가장 유명하고 강력한 동적 웹 어플리케이션 프레임워크 중 하나로 자리잡았습니다. 37signals, GitHub, Shopify, Scribd, Twitter, Disney, Hulu, Yellow Pages 등등 아주 작은 회사에서부터 거대한 기업에 이르기까지 Rails는 폭 넓게 사용되고 있으며, 지금도 많은 회사에서 Rails를 도입하고 있습니다. ENTP, thoughtbot, Pivotal Labs, Hashrocket를 비롯한 많은 컨설턴트와 트레이너들을 시작으로 Rails를 전문적으로 다루는 많은 프로그래머들이 있습니다.

Rails의 어떤 면이 그렇게 대단한 걸까요? 무엇보다도 Rails는 100% 오픈소스이며 MIT 라이센스를 채용하고 있어 사용에 큰 제약이 따르지 않습니다. 따라서 다운로드는 물론이고, 사용에도 별도의 비용이 들지 않습니다. Rails의 또 다른 성공 요인 프레임워크를 기술하고 있는 Ruby은 언어의 유연함을 활용해, 웹 어플리케이션 프로그래밍에 특화된 DSL(도메인 고유 언어)을 만들어 우아하고 깔끔한 디자인으로 만들어졌다는 점입니다. 따라서 HTML 생성, 데이터 모델, URL 라우팅 등등 웹 프로그래밍에 필요한 다양한 작업을 좀 더 읽기 쉽고 짧은 코드로 구현할 수 있습니다.

또한 Rails는 새로운 웹 기술과 프레임워크 디자인을 빠르게 적용해나갔습니다. 예를 들어 Rails는 웹 어플리케이션 구성에 있어 REST 아키텍처를 가장 빨리 도입했던 프레임워크 중 하나입니다(REST에 관해서는 튜토리얼을 진행하는 과정에서 더 자세히 설명합니다). 그리고 David Heinemeier Hansson을 필두로 한 Rails 코어팀은 다른 프레임워크의 좋은 점들은 망설임없이 받아들였습니다. Rails의 가장 큰 라이벌이었던 Merb 프레임워크와 통합한 예를 꼽을 수 있습니다. 그 결과 Rails에서도 Merb의 모듈화된 디자인과 안정된 API를 활용할 수 있게 되었습니다.

마지막으로 다양한 경력을 가진 프로그래머들이 모여있는 열정적인 커뮤니티를 들 수 있습니다. 수백명에 이르는 오픈소스 컨트리뷰터와 많은 사람들이 모이는 관련 컨퍼런스, 페이지네이션과 이미지 업로드 등 각종 기능을 제공하는 gem, Rails를 다루는 다양한 블로그, 포럼, 게시판, IRC 채널들이 Rails 커뮤니티를 구성하고 있습니다. 수많은 Rails 프로그래머 덕분에 대부분의 어플리케이션 에러는 구글에 검색만 해도 관련된 포스트나 게시물을 찾을 수 있습니다.

1.1.1 독자 여러분에게

Rails 튜토리얼에선 Rails 뿐만 아니라 Ruby 언어, Rspec 테스트 프레임워크, HTML, CSS, 약간의 JavaScriptSQL을 아주 조금 다루고 있습니다. 당장 여러분의 Web 프로그래밍에 관련된 지식에 관계없이 이 튜토리얼을 마칠 때 쯤에는 좀 더 어려운 주제의 글들을 읽을 수 있음은 물론 각 주제를 좀 더 체계적으로 다룰 수 있을 정도의 실력을 갖추게 됩니다. 바꿔말하면 여전히 다뤄야될 수많은 주제들이 남아있다는 이야기입니다. 경험이 적은 프로그래머는 이 거대한 정보량에 압도될 지도 모릅니다. 프로그래밍 경험에 따라 짧은 조언이 준비되어있으니참고하시기바랍니다.

모든 독자에게: 자주 받는 질문 중 하나가 Rails를 배우기 전에 반드시 Ruby를 배워야만 하는지 여부입니다. 이는 여러분의 학습 스타일과 프로그래밍 경험에 달린 문제입니다. 기초부터 체계적으로 공부하고 싶거나 프로그래밍 경험이 전혀 없는 분이라면 Ruby부터 배우는 편이 좋습니다. 이런 분들에게는 Peter Cooper의 'Beginning Ruby'를 추천합니다. 하지만 많은 Rails 입문자들은 Web 어플리케이션을 만드는 데 더 많은 관심이 있고, 하나의 웹 페이지를 만드는 데 500페이지가 넘는 Ruby 책을 읽고 싶다는 생각은 하지 않겠죠. 이런 분들은 대화형 Ruby 학습 서비스인 Try Ruby2로 중요한 부분들을 공부하시고 필요에 따라서 Rails for Zombies3를 통해 Rails로 무엇을 할 수 있는지 공부하시기 바랍니다.

또 하나 자주 받는 질문은 테스트를 처음부터 도입해도 괜찮은가 하는 질문입니다.'시작하며'에서 이야기했듯이 Rails 튜토리얼에서는 처음부터 테스트 주도 개발(TDD)을 합니다. TDD는 제가 생각하는 Rails 어플리케이션을 만드는 데 가장 좋은 방법이긴 하지만, 그만큼 복잡하고 배워야하는 내용도 많습니다. 처음 읽어나갈 때 테스트가 귀찮거나 어려워서 진행이 더뎌진다면 테스트는 과감히 생략해버리셔도 좋습니다. 더 좋은 방법은 테스트 코드를 지금 작성한 코드가 제대로 작동하는지 확인하기 위한 도구로만 사용하는 겁니다. 두번째 제시한 방법을 적용하고자 하신다면, spec이라고 불리는 테스트 파일을 만들고 이 책에 나온대로 그대로 테스트 코드를 옮겨적으시기만 하면 됩니다. 처음에 테스트를 실행하면 테스트는 실패합니다만, 다시 튜토리얼을 따라 코드를 작성하고 테스트를 다시 실행하면 테스트가 통과되도록 구성되어있습니다(이는 5장에서 더 자세히 설명합니다).

경험이 적은 프로그래머: Rails 튜토리얼은 프로그래밍 경험이 전혀 없는 사람들을 위한 입문서가 아닙니다. 웹 어플리케이션은 아무리 간단한 어플리케이션이래도 본질적으로 복잡한 프로그램입니다. 웹 프로그래밍을 아예 처음 접해 Rails 튜토리얼이 어렵게 느껴지는 분들은 HTML이나 CSS의 기초부터 공부하시기 바랍니다. 그리고 Rails 튜토리얼을 다시 읽어주세요. (아쉽게도 개인적으로 추천할만한 교재는 떠오르지 않습니다만, HTML을 배우는 데는 'Head First HTML'이 괜찮아보입니다. 또한 어느 독자 분께선 David Sawyer McFarland의 'CSS: The Missing Manual'를 추천해주셨습니다.)Peter Cooper의 'Beginning Ruby' 앞부분을 읽어보는 것도 좋은 방법입니다. Beginning Ruby에선 제대로된 웹 어플리케이션을 만들어보기 전에 좀 더 간단한 루비 어플리케이션을 만들어 볼 수 있습니다. 사실 많은 입문자들이 이책을 통해 웹 프로그래밍을 배우려고 하고 있습니다. 저 또한 그 분들이 도전해보기를 바랍니다. 이러한 분들에게는 'Rails Tutorial 스크린캐스트 시리즈4를 강력히 추천해드립니다. 이 스크린캐스트에서는 Rails 프로그래밍 과정을 어깨너머로 보며 공부할 수 있습니다.

프로그래밍을 해본 경험이 있고 Web 개발을 시작하시는 분: 이미 프로그래밍 경험이 있는 분들은 클래스, 메소드, 자료구조 같은 용어가 친숙하실 겁니다. Java나 C/C++에 익숙하신 분들은 Ruby 문법이 낯설게 느껴지실지도 모릅니다만 금방 적응하실 겁니다(만약 적응이 정 안 되신다면 루비 코드의 행 마지막에 세미콜론을 사용해 그리움을 달래셔도 좋습니다). 웹 프로그램 고유의 개념들은 Rails 튜토리얼에서 다루고 있습니다. 따라서 지금 POSTPATCH의 차이를 모른다고 문제가 되지는 않습니다.

Web 프로그래밍 경험이 있고, Rails를 처음 시작하는 분: PHP나 Python 같은 동적 언어를 사용하신 적이 있다면 이 책이 어렵게 느껴지지 않을 것입니다. 특히 Python 경험은 도움이 많이 됩니다. 웹 프로그래밍 전반에 대한 사항은 대개 비슷합니다만 테스트 주도 개발(TDD)이나 REST 스타일에 대해서는 처음 접하실지도 모릅니다. Ruby 고유의 특징들도 마찬가지입니다.

Rails를 사용해본 적이 없는 경험 있는 Ruby 프로그래머: Rails를 모르는 Ruby 프로그래머는 현재 거의 없다고 생각됩니다. 만약 그런 Ruby에만 뛰어난 프로그래머라면 이 책을 훑어만 봐도 바로 자신만의 Rails 어플리케이션을 프로그래밍할 수 있을 것입니다.

Rails 프로그래밍 경험이 적은 분: 이미 다른 튜토리얼을 보셨거나 소규모 Rails 어플리케이션을 만들어 보신 분도 계실 겁니다. 비슷한 입장에 있었던 독자분들에 따르면 그럼에도 이 책에서 많은 것을 배웠다고 이야기해주셨습니다. 다른 무엇보다 이 책에는 여러분이 공부한 자료들보다도 Rails에 관련된 새로운 정보들을 많이 포함하고 있습니다.

Rails 프로그래밍 경험이 많은 분: 이런 분들에겐 이 책이 필요하지 않을 거라 사료됩니다만 경험이 풍부한 Rails 프로그래머 분들도 이 책에서 의외로 많은 것을 배웠다고 이야기해주셨습니다. 또 다른 시점에서 Rails를 접해보고 싶으시다면 가볍게 즐기시기 바랍니다.

Ruby on Rails 튜토리얼을 끝까지 읽은 분들에게는 Ruby에 대해 좀 더 심화된 내용을 다루고 있는 책들을 추천합니다. 특히 The Well-Grounded Rubyist(David A. Black), Eloquent Ruby(Russ Olsen), 그리고 주제별로 잘 구성되어있는 The Ruby Way(Hal Fulton)를 추천합니다.

이 과정을 전부 끝내신 분들은 이제 좀 더 어려운 자료 정보원을 탐독해나가셔도 좋습니다. 그 중에서도 제가 추천하는 자료들은 다음과 같습니다.

  • RailsCasts (Ryan Bates) : 훌륭하고 (거의) 공짜인 스크린캐스트
  • PeepCode: 훌륭한 유료 스크린캐스트
  • Code School: 대화형 인터프리터로 프로그래밍을 배울 수 있는 코스
  • Rails Guides: 주제별로 정리된 레일스 공식 가이드 문서
  • RailsCasts (Ryan Bates): RailsCasts를 이미 얘기했었나요? 강력 추천합니다.

1.1.2 Rails와 '확장(Scaling)'에 대해

본격적으로 시작하기 전에 한 가지만 더 이야기하고자 합니다. 예전부터 Rails 프레임워크의 한계로서 자주 언급되는 부분이 확장성에 관한 부분입니다. Rails는 많은 데이터와 사용자에 의해 발생되는 트래픽을 감당할 수 없다는 이야기가 자주 나옵니다. 하지만 여기서 '확장을 한다'는 말은 프레임워크를 확장한다는 의미가 아니라 웹사이트를 확장한다는 의미입니다. Rails가 아무리 훌륭하다고는 해도 프레임워크에 지나지 않습니다. 따라서 Rails를 확장할 수 있느냐가 문제가 아니라, 확장할 수 있는 어플리케이션을 Rails로 작성할 수 있느냐가 문제입니다. 사실 둘 중 어느 질문을 들이민데도, 세계에서 트래픽이 가장 많은 사이트들에서 Rails가 사용되고 있는 상황에서 답은 이미 나와있습니다. 확장성 자체에 관한 논의는 Rails를 넘어서는 주제입니다. 하지만 분명한 사실은 만약 여러분의 웹 사이트에서 Hulu나 Yellow Pages만큼 많은 트래픽이 발생한대도 Rails가 여러분의 야심에 발목을 잡지는 않을 거라는 점입니다.

1.1.3 이 책에서 사용하는 표기법

이 책에서 사용하는 표기법은 가능하면 자체적으로 완결되도록 구성되어 있습니다. 여기서는 보충 설명이 필요한 부분에 대해서 다루겠습니다.

HTML판과 PDF판 모두 본문에 내부 링크(예: 1.2 절)와 외부 링크(예: Ruby on Rails 다운로드 페이지)를 포함하고 있습니다.

이 책의 많은 예제에서 명령행을 통해 명령어를 입력합니다. 모든 명령행 예제에서는 Unix 스타일의 $ 프롬프트를 사용해 이러한 사실을 암묵적으로 전달합니다.

$ echo "hello, world"
"hello world"

윈도우를 사용하시는 분들은 윈도우 명령행에서 > 프롬프트를 사용한다는 사실을 인지해주시기 바랍니다.

C:\Sites> echo "hello, world"
"hello world"

Unix를 기반으로 하는 시스템들에서는 명령어 앞에 sudo를 사용하곤 합니다. 이는 substitute user do의 줄임말로 다른 사용자의 권한으로 명령어를 실행할 수 있게 해주는 명령어입니다. 기본적으로 sudo 명령어를 통해 다른 명령어를 실행하면 관리자 권한으로 프로그램이 실행됩니다. 이를 통해 일반 사용자가 접근할 수 없는 파일이나 디렉토리에 접근할 수 있게됩니다. 1.2.2 절의 예를 보면:

$ sudo ruby setup.rb

1.2.2.3 절에서 추천하는 Ruby Version Manager(rvm)을 사용하지 않으면 유닉스/리눅스/OS X 시스템에선 대부분의 명령어를 sudo로 실행시켜야만 합니다. rvm을 사용하면 다음 명령어로 대신할 수 있습니다.

$ ruby setup.rb

Rails는 명령행에서 실행할 수 있는 여러가지 명령어를 가지고 있습니다. 1.2.5 절의 예에서 처럼 아래 명령어를 사용해 프로그래밍 과정에서 사용할 웹 서버를 로컬에서 실행시킬 수 있습니다.

$ rails server

또한 명령행 프롬프트와 마찬가지로 디렉토리 구분 문자열도 Unix 방식인 슬래시(/)로 나타냅니다. 예를 들어 제 샘플 어플리케이션은 아래 디렉토리에 있습니다.

/Users/mhartl/rails_projects/sample_app

윈도우의 경로라면 아래와 비슷하겠죠.

C:\Sites\sample_app

Rails 어플리케이션의 루트 디렉토리를 Rails 루트라고들 합니다만,이 용어는 Rails 프레임워크 자체의 루트 디렉토리와 혼란의 여지가 있습니다. 이 책에서는 Rails 루트를 Rails 어플리케이션의 루트 디렉토리를 나타내는 용어로만 사용하며, 모든 디렉토리는 이를 기준으로 상대 경로로 나타냅니다. 예를 들어 샘플 어플리케이션의 config 디렉토리는 아래 경로에 존재합니다.

/Users/mhartl/rails_projects/sample_app/config

이 Rails 어플리케이션의 루트 디렉토리는 config 디렉토리보다 한 단계 위에 있는 디렉토리로 아래와 같습니다.

/Users/mhartl/rails_projects/sample_app

아래의 경로를 간략히 나타낼 때

/Users/mhartl/rails_projects/sample_app/config/routes.rb

이 책에서는 어플리케이션의 루트 경로를 생략하고 간단히 config/routes.rb로 나타냅니다.

Rails 튜토리얼에는 쉘 스크립트, 버전 관리 상태, 루비 프로그램을 비롯한 다양한 출력 결과가 포함되어있습니다. 시스템에 따라 이러한 출력 결과들은 약간의 차이가 있을 수 있으, 따라서 실제 결과가 이 책의 출력며 결과가 완전히 일치하지는 않을 수도 있습니다. 하지만 대개 이는 큰 문제가 되지 않으니 신경쓰지 않으셔도 괜찮습니다.

시스템에 따라 일부 명령어가 에러를 발생시키는 경우도 있습니다. 모든 상황을 가정해 발생할 수 있는 온갖 문제들에 대해서 해결해드리는 일은 포기했습니다. 문제가 발생하면 에러 메시지를 Google에서 검색해보시기 바랍니다. 이는 많은 프로그래머들이 실제로 애용하는 방법입니다. 이 튜토리얼을 따라하는 과정에서 문제가 발생한다면 Rails 튜토리얼 Help 페이지의 리소스들을 참조해주시기 바랍니다.

1.2 개발 환경 구축과 Rails 실행하기

이 책의 1장은 이른바 로스쿨의 '제초기간(weeding out phase)'(≈선별기간)에 해당합니다. 여기서 개발 환경 구축에 성공한다면 나머지 부분은 쉽게 해쳐나갈 수 있습니다.
—Bob Cavezza (Rails 튜토리얼 독자)

Ruby on Rails 개발환경을 구축하고 첫 어플리케이션을 만들어볼 시간입니다. 프로그래밍 경험이 없는 분에게는 조금 어려울지도 모르지만 모두 힘내시길 바랍니다. 개발환경 구축이 어려운 건 결코 여러분 혼자가 아닙니다. 프로그래머라면 누구나 거쳐가야하는 길이며, 어려운만큼 그에 마땅한 충분한 보상이 있으리라 보장합니다.

1.2.1개발환경

프로그래머들이 자신만의 방법으로 개발환경을 커스터마이징하는 걸 생각해보면, Rails 개발환경 역시 Rails 프로그래머 수만큼 존재합니다. 하지만 크게 두 타입으로 나눠 볼 수 있습니다. 텍스트 에디터와 명령행을 사용하는 환경과 IDE(통합개발환경)를 사용하는 경우입니다. 우선은 IDE부터 살펴보도록 하죠.

IDE

Rails 프로그래밍에 사용할 수 있는 IDE로는 RadRailsRubyMine이 유명합니다. 특히 RubyMine이 유명하며 David Leoffler라는 독자가 'Rails 튜토리얼에서 RubyMine을 사용하는 방법8' 에 관하여 별도의 문서로 정리해두었습니다. IDE를 사용하고 싶으신 분은 직접 자신에게 적합한 IDE를 찾아보시기 바랍니다.

텍스트 에디터와 명령행

저는 IDE 대신에 텍스트 에디터로 소스 코드를 편집하고 명령행에서 명령어를 실행시키는 방법을 더 선호합니다. 여러가지 텍스트 에디터와 터미널 프로그램들 중에서 어떤 조합을 사용할 지는 여러분의 취향과 시스템에 달려있습니다.

  • 텍스트 에디터: 저는 Sublime Text 2를 강력히 추천합니다. Sublime Text는 매우 뛰어난 크로스 플랫폼 텍스트 에디터로, 배우기도 쉽고 다양하고 강력한 기능들을 가지고 있습니다. 또한 TextMate의 영향을 강하게 받았으며, 컬러 스킴과 스니펫은 TextMate와 호환됩니다(Mac을 사용하신다면 TextMate 역시 여전히 좋은 선택지입니다). 두번째로 추천하는 텍스트 에디터는 Vim10입니다. Vim 역시 여러 시스템에서 사용할 수 있습니다. 또한 Sublime Text는 유료인데 반해, Vim은 무료입니다. 둘 다 실제 프로그래밍에 사용할 수 있는 훌륭한 텍스트 에디터지만, 제 경험에 의하면 Sublime Text 쪽이 입문자에게는 훨씬 사용하기 편한 에디터입니다.
  • 터미널: OS X를 사용하신다면 iTerm이나 운영체제에서 기본으로 지원하는 Terminal app을 추천합니다. Linux를 사용하신다면 기본 터미널을 사용하시면 됩니다. 윈도우에선 Rails를 직접 사용하기 보다 Linux 가상 머신을 설치하는 걸 선호하시는 분이 많습니다. 이 경우엔 Linux와 마찬가지로 기본 터미널을 사용하시면 됩니다. 개발환경을 윈도우 자체에 구축한 경우엔 Rails 인스톨러에 포함된 명령행을 사용하시기 바랍니다.

Sublime Text의 옵션 설정 방법은 Rails 튜토리얼: Sublime Text11에서 좀 더 자세히 다루고 있습니다. (링크된 문서에서 다루는 내용은 설정 과정에서 에러가 발생할 가능성이 많습니다. 프로그래밍이 익숙하신 분들에게 추천합니다. 추가 설정을 하지 않아도 Sublime Text는 Rails 어플리케이션을 프로그래밍하는 데 이미 훌륭한 텍스트 에디터입니다.)

editor_shell
그림 1.1 텍스트 에디터/명령행 개발환경(TextMate/ITERM을 사용)(확대)

브라우저

많은 종류의 브라우저가 있습니다만 대부분의 Rails 프로그래머는 Firefox, Safari, Chrome 중 하나를 사용하는 경향이 있습니다. 이 브라우저들은 웹 페이지의 임의의 요소에 대한 정보를 바로 살펴볼 수 있도록 "Inspect element" 기능을 지원하고 있습니다(마우스 오른쪽 버튼을 누르면 나오는 문맥 메뉴에서 찾을 수 있습니다).

그 외의 툴에 대해

직접 개발환경을 구축해 보시면 모든 부분을 생각대로 작동시키는 것만 해도 상당히 많은 시간이 걸린다는 걸 실감하실 겁니다. 특히 마음에 맞는 에디터를 찾고 튜토리얼만 따라해보는 데도 몇 주는 족히 걸립니다. 이 게임에 처음 뛰어든 여러분에게 이런 조언을 드리고싶습니다. 개발환경을 구축하고 프로그래밍에 관련된 도구를 공부하는 데 많은 시간이 걸리는 건 지극히 당연한 일입니다. 이것 또한 프로그래머라면 누구나가 거치는 과정입니다. 이러한 과정은 어렵습니다. 여러분의 머리 속을 스쳐가는 끝내주는 아이디어를 구현하기 위해 당장 Rails에 올라타고 싶겠지만, 그 시작을 위해서 괴상해보이는 고대의 Unix 에디터도 배워야만 합니다. 하지만 기술자라면 자신이 사용할 도구에 대해서 필히 이해하고 있어야 합니다. 그러한 고된 노력은 반드시 보상받게 되어있습니다.

1.2.2Ruby, RubyGems, Rails, Git

사실상 세상에 있는 모든 소프트웨어는 망가져 있거나 사용하기 어렵다. 그래서 사람들은 소프트웨어를 두려워한다. 사람들은 무언가를 설치하고 심지어 온라인 폼을 채워나가지만 제대로 작동하지 않는데 익숙해져있다. 나는 무언가 설치하는 게 두렵고, 나는 공퓨터 공학박사다.
—「Founders at Work」(Jessica Livingston저)의 Paul Graham 발언.

이제 Ruby와 Rails를 설치해보겠습니다. 가능한 한 많은 환경을 다루려고 노력했습니다만, 시스템에 따라서는 문제가 발생할 수도 있습니다. 문제가 발생하면 에러 메시지를 구글에 검색해보거나 Rails 튜토리얼 Help 페이지를 참고하시기 바랍니다.

따로 언급이 없는한, 이 책과 같은 결과를 보고 싶으시다면 Rails를 포함한 모든 소프트웨어는 이 책에서 언급한 버전을 사용해야만 합니다. 마이너 버전이 다르더라도 같은 결과를 얻을 수 있지만 그러한 결과에 의존하지 마시기 바랍니다. 특히 Rails는 반드시 튜토리얼에서 언급한 버전을 사용하시기 바랍니다. 단 Ruby 프로그래밍 언어는 예외입니다. 이 튜토리얼을 진행하는 데 있어 1.9.3와 2.0.0 어느 버전을 사용해도 실질적인 차이는 없습니다. 사용하고 싶은 버전을 사용하시면 됩니다.

Rails인스톨러 (Windows)

바로 얼마 전까지만 해도 Windows에서 Rails를 설치하는 일은 까다로운 작업이었습니다. 하지만 Engine Yard(특히 Nic Williams와 Wayne E. Seguin) 덕분에 쉽게 설치할 수 있는 방법이 생겼습니다. Windows 사용자 분들은 Rails 인스톨러에서 인스톨러를 다운로드해주세요. 설치 과정을 소개한 스크린캐스트도 준비되어있습니다. 인스톨러를 실행시키고 지시에 따라 Git, Ruby, RubyGems 그리고 Rails를 설치하시기 바랍니다. (1.2.2.2, 1.2.2.3, 1.2.2.4, 1.2.2.5는 넘기셔도 됩니다.)설치가 끝나면 1.2.3 절로 넘어가 첫 Rails 어플리케이션을 만들어보시기 바랍니다.

단, Rails 인스톨러를 사용해 설치하는 경우엔 Rails 버전이 1.2.2.5 절에서 언급한 버전과 다를 수 있으므로 주의가 필요합니다. 현재 Rails 인스톨러를 개발중인 Nic, Wayne와 함께 Rails 인스톨러가 버전 순으로 정렬될 수 있도록 조치중에 있습니다.

Git 설치

Rails 생태계는 Git라고 하는 버전 관리 시스템에 많은 부분을 의존하고 있습니다(자세한 내용은 1.3에서 설명합니다). Git는 이 책 전반에 걸쳐 사용되므로 미리 설치해둘 필요가 있습니다. Pro Git의 'Git 설치'에서 시스템 별 설치 방법을 참고해주세요.

Ruby 설치

다음으로 Ruby를 설치합니다(Ruby를 설치하는 과정에 자잘한 에러가 발생하곤 합니다. 고백하건데 새로운 버전의 Ruby를 설치하는 데서 두려움마저 느껴집니다만, 튜토리얼 진행을 위해선 피해나갈 수 없는 과정입니다).

이미 시스템 상에 Ruby가 설치되어있을 수도 있습니다. 아래 명령어를 실행해서

$ ruby -v

버전 정보를 확인해보시기 바랍니다. Rails 4를 사용하려면 Ruby 1.9 이상이 반드시 필요하며 Ruby 2.0에 최적화 되어있습니다(Ruby 1.8.7에선 Rails4를 사용할 수 없습니다). 이 튜토리얼에서는 Ruby 1.9.3이나 2.0.0을 사용한다고 전제하고 있지만 Ruby 1.9.2를 사용해도 큰 문제는 없습니다.)

OS X나 Linux를 사용하신다면 Ruby Version Manager(RVM)이나 rbenv를 사용해 Ruby를 설치하시기 바랍니다. RVM을 사용하면 같은 시스템에서 여러 버전의 Ruby를 동시에 사용할 수 있습니다( 윈도우엔 같은 역할을 하는 Pik라는 프로그램이 있습니다). 같은 시스템에서 서로 다른 버전의 Ruby와 Rails를 실행하려는 경우 특히 중요합니다. 단 RVM과 rbenv를 같은 시스템에서 동시에 사용할 순 없습니다. 저는 RVM을 사용해 왔기에 이 튜토리얼에서도 RVM을 기준으로 설명해나가겠습니다. rbenv도 호평을 받고 있으니 이미 rbenv를 사용하고 있거나 잘 아시는 분이 주변에 있다면 RVM 대신에 rbenv를 사용하셔도 됩니다.

Mac OS X 사용자는 Xcode 개발 툴(Xcode developer tools)을 설치할 필요가 있습니다. Xcode 전체를 설치하는 데는 많은 용량이 필요하므로 대신에 Command Line Tools for Xcode 설치를 추천합니다.12

Ruby를 설치하기 전에 아래 명령어로 RVM을 설치하시기 바랍니다.

$ curl -L https://get.rvm.io | bash -s

(이미 RVM이 설치되어있다면 아래 명령어를 실행해서

$ rvm get stable

최신 버전의 RVM을 사용합니다.)

RVM을 설치한 다음엔 아래 명령어를 사용해 Ruby 설치에 필요한 사항을 확인합니다.

$ rvm requirements

제 시스템에서는 아래의 패키지들을 설치해야했습니다(여기서는 Mac OS X에서 사용할 수 있는 패키지 관리 시스템인 Homebrew를 사용합니다.).

$ brew install libtool libxslt libksba openssl

Linux에선 apt-get이나 yum을 사용해서 설치합니다.

제 시스템에선 YAML 라이브러리도 설치할 필요가 있었습니다.

# Mac에서 Homebrew를 사용하는 경우
$ brew install libyaml

# Debian 기반의 Linux 시스템의 경우
$ apt-get install libyaml-dev

# Fedora/CentOS/RHEL Linux 시스템의 경우
$ yum install libyaml-devel

마지막으로 아래 명령어로 Ruby 2.0.0을 설치합니다. 여기서는 OpenSSL의 위치를 지정하기 위한 옵션을 사용했습니다.

$ rvm install 2.0.0 --with-openssl-dir=$HOME/.rvm/usr
<잠시 기다립니다>

(Mac에선 openssl 경로를 --with-openssl-dir=$HOME/.rvm/opt/openssl 으로 지정해줍니다.)

안타깝게도 Ruby나 RVM 설치 과정에서 여러 문제가 발생하곤 합니다. 이 책에서는 가능한 한 포괄적으로 설치 과정에 대해서 설명하고 있습니다만, 유일한 일반적 해결방법은 인터넷을 검색해보는 방법 뿐입니다.

Ruby를 설치하고 나면, Rails 어플리케이션을 실행할 수 있도록 다른 필요한 프로그램을 설치하고 시스템을 설정해주어야합니다. 여기엔 일반적으로 gem 설치를 포함됩니다. gem은 자기완결형 Ruby 코드 패키지(self-contained packages)를 의미합니다. gem의 버전에 따라 gem들간에 충돌이 발생할 수 있기 때문에 특정 버전의 gem들을 모아 gemset을 만들어 사용할 수 있습니다.아래 명령어를 실행해서 튜토리얼 진행에 사용할 railstutorial_rails_4_0이라는 gemset을 만들어주시기 바랍니다.

$ rvm use 2.0.0@railstutorial_rails_4_0 --create --default
Using /Users/mhartl/.rvm/gems/ruby-2.0.0-p0 with gemset railstutorial_rails_4_0

명령어를 실행하면 Ruby 2.0.0을 사용하는 railstutorial_rails_4_0 gemset이 만들어지고(--create) 해당하는 gemset을 사용하도록 설정합니다.use). 마지막으로 --default 옵션은 railstutorial_rails_4_0을 기본 gemset으로 설정합니다. 이제 터미널 윈도우를 실행하면 2.0.0@railstutorial_rails_4_0 버전의 Ruby와 gemset 조합이 자동적으로 선택됩니다. RVM은 gemset 관리를 위한 여러가지 명령어를 가지고 있습니다. 자세한 내용은 http://rvm.beginrescueend.com/gemsets/를 참조해주세요. RVM이 제대로 실행되지 않으면 아래 명령어로 도움말을 출력해보시기 바랍니다.

$ rvm --help
$ rvm gemset --help

RVM에 대한 자세한 설명은 'Rails 입문자를 위한 Ruby Version Manager(RVM) 개요' 문서를 참고하시기 바랍니다13.

RubyGems 설치

RubyGems는 Ruby 프로젝트 관리를 위한 패키지 매니저 입니다. 또한 루비 패키지나 gem으로 사용할 수 있는 많은 라이브러리들이 있습니다. Rails 또한 이 중 하나입니다. Rails도 하나의 gem으로 설치합니다. Ruby가 설치되어있다면 RubyGems를 설치하는 일은 간단합니다. RVM이 설치되어 있으면 이미 RubyGems도 설치되어 있을 겁니다.

$ which gem
/Users/mhartl/.rvm/rubies/ruby-2.0.0-p0/bin/gem

RubyGems가 설치되어 있지 않으면 RubyGems를 다운로드해서 압축을 풀고, 만들어진 rubygems 디렉토리로 이동해 setup.rb를 실행시켜줍니다.

$ ruby setup.rb

(권한 문제가 발생하면 1.1.3을 참조해주세요. 아마도 sudo 명령어를 사용해야할 필요가 있습니다.)

이미 RubyGems가 설치되어있으면 튜토리얼에서 사용하는 버전으로 변경해주세요.

$ gem update --system 2.0.3

RubyGems를 특정 버전에 고정해두면 이후 RubyGems가 변경될 때 발생할 수 있는 충돌을 방지할 수 있습니다.

gem을 설치하면 RubyGems에 의해 기본적으로 ri와 rdoc 두 가지 문서가 생성됩니다. 하지만 많은 Ruby와 Rails 프로그래머들은 ri나 rdoc으로 만들어진 문서보다는 온라인 문서를 참조합니다. ri나 rdoc 문서가 생성되지 않도록 하기 위해선 .gemrc 파일을 리스트 1.1처럼 홈 디렉토리에 만들고 리스트 1.2와 같이 수정합니다. (물결표시 "~"는 '홈 디렉토리'를 나타냅니다. .gemrc 파일처럼 점(.)으로 시작하는 파일은 숨겨진 파일로 다뤄집니다. 점으로 시작하는 파일은 설정파일을 나타내는 일반적인 관습입니다.)

리스트 1.1 gem 설정 파일을 생성.
$ subl ~/.gemrc

subl는 OS X에서 Sublime Text를 실행하는 명령어입니다. 설정하는 방법은 'OS X 명령행 : Sublime Text2 문서를 참조해주세요. 사용하는 시스템과 에디터에 따라서 적절히 명령어를 바꿔주시기 바랍니다.(에디터 아이콘을 더블 클릭하거나 mate, vim, gvim, mvim과 같은 명령어를 사용해주세요.) 편의상 이 튜토리얼에서는 subl을 사용하지만, 여러분이 사용하시는 에디터의 명령어를 대신 사용하시면 됩니다.

리스트 1.2 .gemrc에 ri와 rdoc 문서를 생성하지 않도록 하는 옵션을 추가
install: --no-rdoc --no-ri
update:  --no-rdoc --no-ri

Rails 설치

RubyGems를 설치하고 나면 Rails를 인스톨하는 건 쉽습니다. 이 책에서는 Rails 4.0을 사용합니다. 아래의 명령어를 실행해서 Rails를 설치해주시기 바랍니다.

$ gem install rails --version 4.0.0

정상적으로 설치되었는지 확인하기 위해서 아래의 명렁어를 실행해서 버전을 확인해볼 수 있습니다.

$ rails -v
Rails 4.0.0

참고 : 1.2.2.1 절 에서 Rails 인스톨러를 사용한 경우엔 Rails 버전이 다를 수 있습니다. 아직까지는 이 차이로 인해 발생하는 문제가 확인되지 않았습니다. 하지만 이후에 튜토리얼과 Rails 버전의 차이가 더 커지게 되면 문제가 될 수도 있습니다. 현재 특정 버전의 Rails를 설치할 수 있는 Rails 인스톨러에 링크를 걸 수 있도록 Engine Yard 측과 작업을 하고 있습니다.

Linux 시스템을 사용하고 있다면 이 시점에서 몇 가지 패키지를 추가적으로 설치할 필요가 있습니다.

$ sudo apt-get install libxslt-dev libxml2-dev libsqlite3-dev # Linux

1.2.3첫 Rails 어플리케이션(The first application)

어떤 Rails 어플리케이션을 만들 건 간에rails new 명령어로 프로젝트를 생성하는 건 똑같습니다. 이 명령어를 실행하면 지정한 디렉토리에 Rails 어플리케이션의 뼈대를 만들어줍니다. 앞으로 만들게 될 여러 레일스 어플리케이션을 저장할 디렉토리를 만들고, 그 디렉토리에서 rails new 명령어를 실행해 첫 Rails 어플리케이션을 생성합니다(리스트 1.3).

리스트 1.3 rails new 명령어를 통한 어플리케이션 생성.
$ mkdir rails_projects
$ cd rails_projects
$ rails new first_app
      create  
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      .
      .
      .
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
         run  bundle install
.
.
.
Your bundle is complete!Use `bundle show [gemname]` to see where a bundled
gem is installed.

리스트 1.3를 보면 rails new를 실행했을 때, 뼈대 파일들이 만들어지고 bundle install 명령어가 자동적으로 실행되는 걸 볼 수 있습니다. 만약 bundle install이 실행되지 않더라도 걱정하실 필요는 없습니다. 1.2.4의 순서에 따르면 정상적으로 작동됩니다.

rails 명령어를 통해 여러 파일과 디렉토리가 만들어지는 걸 알 수 있습니다. 이러한 표준적인 디렉토리와 파일 구조(그림 1.2)가 정해져있는 있는 건 Rails의 큰 장점 중 하나입니다. 아무것도 없는 상태에서 실행할 수 있는 어플리케이션을 바로 만들 수 있습니다. 또한 모든 Rails 어플리케이션이 같은 구조를 공유하고 있기 때문에 다른 프로그래머의 소스코드를 보더라도 구조를 쉽게 파악할 수 있습니다. Rails가 기본적으로 생성하는 파일들에 관한 내용은 표 1.1 을 참조해주세요. 이 파일들과 디렉토리들의 용도에 관해서는 이 튜토리얼 전반에 걸쳐서 설명해 나갑니다. 특히 5.2.1절부터는 애셋 파이프라인(Asset Pipeline)(Rails 3.1부터 도입)의 일부인 app/assets 디렉토리에 관해서 좀 더 자세히 다룹니다. 애셋 파이프라인은 CSS(Cascading Style Sheet)나 JavaScript 파일들을 구조화와 효율적인 배포하는 데 도움을 줍니다.

directory_structure_rails_4_0
그림 1.2새로 만든 Rails 어플리케이션의 디렉토리 구조(확대)
파일/디렉토리용도
app/모델, 뷰, 컨트롤러, 헬퍼를 비롯한 주요 어플리케이션 코드
app/assets어플리케이션에서 사용하는 CSS(Cascading Style Sheet), JavaScript, 이미지 파일과 같은 애셋 파일
bin/실행가능한 바이너리 파일
config/어플리케이션 설정
db/데이터베이스에 관련된 파일
doc/어플리케이션 문서
lib/라이브러리 모듈
lib/assets라이브러리에서 사용하는 CSS, JavaScript, 이미지 파일과 같은 애셋 파일
log/어플리케이션 로그 파일
public/에러페이지를 비롯한 웹 브라우저를 통해서 직접 접근 가능한 데이터
script/rails코드 생성, 콘솔 실행, 로컬 웹 서버 실행 등 Rails에 관련된 스크립트
test/어플리케이션 테스트 코드(3.1.2절부터 spec/ 디렉토리를 대신 사용합니다.)
tmp/임시 파일
vendor/서드파티 플러그인과 gem
vendor/assets서드파티 플러그인이나 gem에서 사용하는 CSS, Javascript 파일, 이미지 파일과 같은 애셋 파일
README.rdoc어플리케이션에 대한 간단한 설명
Rakefilerake 명령어에서 사용가능한 태스크 정의 파일
Gemfile어플리케이션에 필요한 gem 정의 파일
Gemfile.lock어플리케이션의 복사본에서 같은 버전의 gem 사용을 보장하기 위한 파일(어플리케이션에서 실제 사용되고 있는 gem과 그 버전 목록이 담겨져있습니다).
config.ruRack 미들웨어 설정 파일
.gitignoreGit에서 무시할 파일의 목록을 담은 파일
표1.1: Rails 어플리케이션의 기본적인 구조

1.2.4 Bundler

새로운 Rails 어플리케이션을 만들고 나서 다음으로 해야할 일은 Bundler을 실행해 어플리케이션에 필요한 gem을 설치하고 어플리케이션에 인클루드 하는 일입니다. 1.2.3에서 설명했듯이 Bundler는 rails 명령어에 의해 자동적으로 실행되지만(이 때는 bundle install) 이 절에서는 어플리케이션에서 기본적으로 사용하는 gem을 변경하고 다시 Bundler을 실행시켜 보도록 하겠습니다. 우선은 사용하는 에디터로 Gemfile을 열어주시기 바랍니다.

$ cd first_app/
$ subl Gemfile

현재 Gemfile 파일은 리스트 1.4와 같을 것입니다. Gemfile 역시 Ruby 코드이지만 아직 Ruby 문법에 대해선 걱정하지 않으셔도 됩니다. Ruby 문법에 대한 좀 더 자세한 설명은 제 4장에서 이루어집니다.

리스트 1.4 first app 디렉토리의 자동생성된 Gemfile의 내용
source 'https://rubygems.org'

# Use sqlite3 as the database for Active Record
gem 'sqlite3'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'

# Turbolinks makes following links in your web application faster.
# Read more: https://github.com/rails/turbolinks
gem 'turbolinks'

# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.0.1'

group :doc do
  # bundle exec rake doc:rails generates the API under doc/api.
  gem 'sdoc', require: false
end

# Use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# Use unicorn as the app server
# gem 'unicorn'

# Use Capistrano for deployment
# gem 'capistrano', group: :development

# Use debugger
# gem 'debugger', group: [:development, :test]

대부분의 행은 #으로 주석 처리되어있습니다. 이 주석들은 자주 사용되는 gem과 Bundler의 문법에 대해 알려줍니다. 아직 기본적으로 사용하는 gem 이외의 gem을 추가적으로 설치할 필요는 없습니다.

gem 메소드로 특정 버전을 명시적으로 지정하지 않으면 Bundler는 자동적으로 최신 버전을 설치합니다. 안타깝게도 gem을 업데이트하는 과정에서 작은 문제들이 자주 발생합니다. 따라서 이 튜토리얼에서는 충돌없이 작동하는 게 확인된 gem의 버전을 리스트 1.5처럼 명시적으로 지정해줍니다.(이 때 리스트 1.4에서 주석 처리된 행도 삭제합니다.)

리스트 1.5 사용할 gem들의 버전을 명시적으로 지정한 Gemfile
source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0

gem 'rails', '4.0.0'

group :development do
  gem 'sqlite3', '1.3.7'
end

gem 'sass-rails', '4.0.0'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.0'
gem 'jquery-rails', '2.2.1'
gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'

group :doc do
  gem 'sdoc', '0.3.20', require: false
end

리스트 1.5에는 아래의 행이 추가되어 있습니다.

ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0

위와 같이 어플리케이션에서 사용할 Ruby 버전과 gemset도 명시적으로 지정할 수 있습니다. 이를 통해 RVM gemset(1.2.3)과 함께 어플리케이션을 배포하기가 수월해집니다. 리스트 1.5에서 #으로 시작하는 부분은 Ruby 주석입니다. 이는 RVM을 사용하지 않으면 주석으로 아무런 처리도 일어나지 않습니다만 RVM을 사용하는 경우엔 여기에 지정된 gemset이 사용됩니다. (Ruby 2.0.0 이외의 버전을 사용하신다면 사용하시는 버전으로 이 부분을 수정해주시기 바랍니다.)

이 외에도 Gemfile에서 JQuery에 관련된 부분도 변경된 걸 확인할 수 있습니다. JQuery는 Rails에서 기본적으로 사용하고 있는 자바스크립트 라이브러리입니다.

gem 'jquery-rails'

=>

gem 'jquery-rails', '2.2.1'

이 외에도 변경된 부분이 있습니다.

gem 'sqlite3'

=>

group :development do
  gem 'sqlite3', '1.3.7'
end

Bundler는 이 행에 지정된 대로 sqlite3 gem 1.3.7 버전을 설치합니다. 그리고 SQLite를 development 환경(7.1.1)에서만 사용하도록 설정해두었습니다. 이는 이후에 Heroku(1.4)를 통해 어플리케이션을 배포할 때 사용하는 데이터베이스와 충돌을 막기 위해서입니다.

리스트1.5에서 몇 가지 변경 사항을 더 찾아볼 수 잇습니다.

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

=>

gem 'sass-rails',   '4.0.0'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.0'

아래 코드는

gem 'uglifier', '>= 1.3.0'

ugilfier gem(애셋 파이프라인의 압축을 담당하는 gem)의 버전을 1.3.0 이후의 버전으로 강제한다는 의미입니다. 극단적으로 7.2버전이 최신버전이라도 지정한 버전보다 크기만 하면 설치됩니다. 아래 코드는

gem 'coffee-rails', '~> 4.0.0'

coffee-rails(마찬가지로 애셋 파이프라인에서 사용하는 gem입니다)의 버전을 4.0.0보다 크고 4.1보다 작은 버전으로 강제한다는 의미입니다. 정리하면 >=을 사용할 때 bundle install을 실행하면 반드시 업그레이드가 이루어지지만 ~>4.0.0을 사용하면 마이너 버전의 업그레이드만 이루어집니다. 이 예제에서는 4.0.0에서 4.0.1로 업그레이드 될 수 있지만 4.0에서 4.1로 업그레이드되지는 않습니다. 불행히도 이러한 마이너 버전의 업그레이드조차 자주 문제를 일으킵니다.따라서 Rails 튜토리얼에서는 기본적으로 모든 gem의 버전을 정확히 일치하도록 강제합니다. 경험이 있는 프로그래머라면 Gemfile~>가 지정된 gem을 비롯해 최신 버전의 gem을 사용하셔도 상관없습니다. 단 이 튜토리얼과 실행 결과가 같다는 보장은 할 수 없습니다.

Gemfile을 올바르게 설정하고 나면 bundle update14bundle install 명령어를 실행해서 gem들을 설치합니다.

$ bundle update
$ bundle install
Fetching source index for https://rubygems.org/
.
.
.

bundle install 명령어가 완료되는 데에는 시간이 좀 걸릴 지도 모릅니다. 설치가 끝나면 어플리케이션을 실행할 수 있습니다.

1.2.5 rails server

1.2.3 절rails new 명령어와 1.2.4 절bundle install 명령어를 통해서 실행가능한 어플리케이션이 만들어졌습니다. Rails는 프로그래밍 중인 컴퓨터에서만 접근 가능한 로컬 웹 서버를 실행해주는 프로그램(스크립트)을 가지고 있습니다. 따라서 아래의 명령어를 실행시켜주기만 하면 어플리케이션이 실행됩니다.

$ rails server
=> Booting WEBrick
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server

(자바스크립트 런타임이 설치되어있지 않다는 에러가 발생하는 경우엔, execjs 페이지에 있는 사용가능한 런타임 리스트를 확인해주세요. 개인적으로는 Node.js를 추천합니다) 이제 Rails 어플리케이션이 IP 주소 0.0.0.0, 포트 번호 3000 15에서 실행되고 있습니다.이 IP 주소는, 시스템에 지정된 IP 주소들에 대해서 수신 대기(listen) 상태에 있음을 나타냅니다.따라서 이제 127.0.0.1(localhost)라는 특별한 주소로 어플리케이션에 접속할 수 있습니다.그림 1.3은 웹브라우저에서 http://localhost:3000/에 접속한 화면입니다.

riding_rails_4_0
그림 1.3 Rails의 기본 페이지. (확대)

첫 어플리케이션의 정보를 확인하려면 'About your application’s environment' 링크를 클릭해주세요. 그림 1.4와 같은 화면을 볼 수 있습니다.(그림 1.4는 어플리케이션이 실행될 때의 시스템 정보를 출력해줍니다. 따라서 여러분의 화면은 이 그림의 결과와 다를 수도 있습니다.)

riding_rails_environment_4_0
그림 1.4 어플리케이션 환경이 출력된 기본 페이지. (확대)

물론 프로그래밍을 진행해 나가면서 이 기본 페이지는 필요가 없어집니다만, 당장 어플리케이션을 실행해볼 수 있다는 데 의의가 있습니다. 5.3.2 절에서는 이 기본 페이지를 삭제하고 직접 어플리케이션의 메인 페이지를 구현합니다.

1.2.6 Model-View-Controller (MVC)

이제 시작에 불과하지만 먼저 Rails 어플리케이션의 전체적인 구조에 대해서 알아둘 필요가 있습니다. Rails 어플리케이션의 기본 구조(그림 1.2)를 보면 app/ 디렉토리 아래에 models, views, controllers 디렉토리가 생성되어있는 걸 알 수 있습니다. 이러한 구조를 통해 Rails가 MVC(model-view-controller) 아키텍처 패턴을 따르고 있음을 알 수 있습니다. MVC 패턴에서는 도메인 로직(=비지니스 로직)과 GUI(그래픽 유저 인터페이스)에 직접적으로 연관된 입력/표시 로직을 나눠놓고 있습니다. 웹 어플리케이션에서 도메인 로직은 사용자 정보나 상품 정보를 담고 있는 데이터 모델에 해당하고 인터페이스는 웹 페이지에 해당합니다.

Rails 어플리케이션에 접속을 하게 되면, 브라우저에서는 웹 서버에 request를 보냅니다. request는 요청의 처리를 담당하는 Rails controller로 다시 보내집니다. 요청을 받는 즉시 컨트롤러에서는 미리 만들어진 템플릿을 통해 HTML으로 구성된 view를 생성하고 브라우저에게 되돌려보냅니다. 동적 사이트에서 컨트롤러는 모델과 정보를 교환합니다. 모델은 사용자 정보와 같은 사이트의 요소가 될 수 있는 정보를 담고 있는 Ruby 객체로 데이터베이스와 통신하면서 정보를 가져오거나 저장합니다. 컨트롤러는 모델에서 정보를 가져와 HTML로 구성된 뷰를 생성해 브라우저에 되돌려줍니다.

mvc_schematic
그림 1.5: model-view-controller (MVC) 아키텍처 개념도.

이런 설명이 아직까지 추상적이라고 느껴지실 지도 모르겠지만 지금 설명한 내용은 이후에도 계속 언급되니 너무 걱정하지 않으셔도 됩니다. 2.2.2 절에서 데모 어플리케이션을 다룰 때 MVC 패턴에 대해 더 자세히 이야기합니다. 샘플 어플리케이션에서는 MVC의 세 요소를 모두 사용합니다. 우선 3.1.2 절에서 컨트롤러와 뷰를 사용하고 모델은 6.1 절부터 사용합니다. 7.1.2 절에서는 이 세가지 구성요소를 조합합니다.

1.3 Git를 통한 버전 관리

새로온 Rails 어플리케이션을 만들었으니 버전 관리 시스템을 사용해보도록 하겠습니다. 버전 관리를 반드시 할 필요는 없습니만 많은 Rails 프로그래머들은 버전 관리 시스템을 통해 어플리케이션을 관리하는 걸 필수적인 부분으로 생각하고 있습니다. 이를 사용해 어플리케이션의 변경 이력을 확인할 수 있을 뿐만 아니라 실수로 잘못 삭제한 파일을 복구할 수도 있으며(롤백) 협업을 하는 데도 여러모로 이점이 있습니다. 버전 관리 시스템을 이해하는 건 모든 프로그래머에게 필수적인 소양이라고 할 수 있습니다.

여러가지 버전 관리 시스템이 있습니다만 Rails 커뮤니티에서는 일반적으로 Linus Torvalds가 Linux 커널 관리를 위해 만든 분산형 버전 관리 시스템 Git를 많이 사용합니다. Git 하나만 해도 굉장히 큰 주제이기 때문에 여기서는 간략히만 살펴보겠습니다. 다행히 웹상에는 Git에 관련된 많은 리소스가 있습니다. 그 중에서도 특히 Scott Chacon이 쓴 Pro Git(Apres, 2009)를 추천합니다. Git를 통한 버전관리를 강력히 추천하는 데는 여러가지 이유가 있습니다. 버전관리는 Rails 프로그래밍을 하는데 있어서 실용적일 뿐만 아니라 소스코드를 다른 프로그래머들과 공유하는데 유용합니다. 뿐만 아니 이번 장에서 만드는 어플리케이션을 실제로 라배포하는 데서도 사용합니다(1.4 절).

1.3.1 설치와 설정

Git가 설치되어있지 않다면 우선 1.2.2.2절에 따라 Git를 설치해주시기 바랍니다.(1.2.2.2 절에서 언급했듯이 Pro Git의 'git 설치' 부분을 참조해주세요)

첫 시스템 설정

Git를 설치하고 딱 한 번 설정할 것들이 있습니다. 이는 system 셋업이라고 불리며 컴퓨터마다 한 번 만 해주면 됩니다.

$ git config --global user.name "이름"
$ git config --global user.email your.email@example.com

checkout이 길게 느껴지신다면 co라는 별칭을 지정해 사용할 수도 있습니다. 별칭을 지정하려면 아래의 명령어를 실행하세요.

$ git config --global alias.co checkout

이 책에서는 co 별칭을 사용하지 않는 분들을 위해서 checkout이라는 명령어를 사용하겠습니다만, 저는 항상 git co를 사용합니다.

마지막으로 Git 커밋 메시지를 입력할 때 사용할 에디터를 지정합니다. Sublime Text, TextMate, gVim, MacVim 등 GUI 에디터를 사용하시는 경우엔 쉘에서 바로 벗어나버리지 않도록 옵션을 붙여줄 필요가 있습니다.

$ git config --global core.editor "subl -w"

"subl -w" 부분을 에디터에 따라서 수정해주시기 바랍니다. TextMate는 "mate -w", gVim는 "gvim -f", MacVim는 "mvim -f"으로 수정하시면 됩니다.

첫 저장소 셋업

이번에는 저장소를 만들어보겠습니다. 우선 Rails 어플리케이션이 있는 디렉토리로 이동해서 새로운 저장소를 초기화합니다.

$ git init
Initialized empty Git repository in /Users/mhartl/rails_projects/first_app/.git/

다음으로 어플리케이션 파일들을 저장소에 추가합니다. 이 때 작은 문제가 하나 있습니다. Git는 기본적으로 모든 파일의 변경 이력을 관리하지만, 관리할 필요가 없는 파일들이 있습니다. 예를 들어 Rails 어플리케이션에 의해 자동으로 생성되는 로그 파일은 그 내용이 빈번히 추가되기 때문에 버전 관리를 할 필요가 없습니다. 이런 파일들을 관리 대상에서 제외시키기 위해서 .gitignore 파일을 이용합니다. 이 파일은 어플리케이션의 루트 디렉토리에 위치해야하며 제외 규칙을 포함하고 있습니다.17

다시 표 1.1을 살펴보면 rails 명령어를 실행했을 때 어플리케이션 루트 디렉토리에 .gitigrone 파일도 함께 만들어진 걸 알 수 있습니다.(리스트 1.6)

리스트 1.6 rails 명령어로 생성된 .gitignore의 내용.
# See http://help.github.com/ignore-files/ for more about ignoring files. #
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
#   git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

리스트 1.6의 규칙에 따라 로그 파일 및 임시 파일(tmp)과 Sqlite 데이터베이스 파일은 관리대상에서 제외됩니다. (예를 들어 log/ 디렉토리 아래의 로그파일을 제외하고 싶다면, log/*.log를 지정해 파일명이 .log 끝나는 파일들을 제외시킬 수 있습니다) 리스트에 열거된 파일들은 자주 그리고 자동적으로 변하는 경우가 많은 파일들로 버전 관리 대상에 포함시킬 필요가 없습니다. 또한 다른 프로그래머들과 협업을 하는 과정에서 예상치 못한 충돌(conflict)를 일으킬 수도 있습니다.

자동으로 작성된 리스트 1.6.gitignore를 그대로 사용하셔도 좋지만, 프로그래밍 과정의 불편함을 줄이고 보안(리스트 3.2)을 강화하기 위해서 리스트 1.7과 같이 수정하는 걸 추천합니다. 수정된 .gitignore 파일에선, Rails 도큐멘트 파일을 비롯해 Vim과 emacs의 스왑 파일, (OS X 사용자에게는 친숙한) Finder에 의해 자동생성되는 .DS_Store 파일도 제외시킵니다. 이 확장된 .gitignore를 사용하고 싶으시면 사용하는 텍스트 에디터로 파일을 열고 리스트 1.7으로 내용을 덮어씁니다.

리스트 1.7 더 강화된 .gitignore 파일
# Ignore bundler config. /.bundle

# Ignore the default SQLite database.
/db/*.sqlite3
/db/*.sqlite3-journal

# Ignore all logfiles and tempfiles.
/log/*.log
/tmp

# Ignore other unneeded files.
doc/
*.swp
*~
.project
.DS_Store
.idea
.secret

1.3.2 추가와 커밋

마지막으로 새롭게 만든 Rails 어플리케이션을 Git에 추가하고 커밋하는 방법에 대해서 알아보겠습니다. 아래 명령어를 실행시켜 파일을 추가합니다(.gitignore에 지정한 파일들은 제외됩니다).

$ git add . 

여기서 '.'은 현재 작업중인 디렉토리를 의미합니다. Git는 지정된 대상의 파일들을 재귀적으로 추가하므로 자동적으로 모든 서브 디렉토리도 추가됩니다. 이 명령어를 통해 프로젝트의 파일들을 실제 반영 전 대기 장소에 해당하는 스테이징 공간(staging area)에 추가시킵니다.스테이징 공간에 있는 파일들은 status 명령어를 통해 확인할 수 있습니다. 18

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   README.rdoc
#       new file:   Rakefile
.
.
.

(출력 결과가 길므로 샐략된 부분을 나타내기 위해 아래로 .을 늘여놨습니다.)

변경 사항을 저장하기 위해서 commit 명령어를 사용합니다.

$ git commit -m "Initialize repository"
[master (root-commit) df0a62f] Initialize repository
42 files changed, 8461 insertions(+), 0 deletions(-)
create mode 100644 README.rdoc
create mode 100644 Rakefile
.
.
.

-m 옵션을 통해 커밋에 메시지를 남길 수 있습니다. -m이 지정되지 않으면 1.3.1에서 설정된 에디터가 자동으로 실행되고, 해당하는 에디터에서 메시지를 입력할 수 있습니다.

Git의 커밋은 어디까지나 커밋이 수행된 로컬 머신에만 저장한다는 점을 이해할 필요가 있습니다. 이는 또 다른 유명한 오픈소스 버전 관리 시스템인 서브버전과 확연히 다른 특징입니다. 서버 버전의 커밋은 원격 저장소를 바로 수정합니다. 반면에 Git에서는 커밋이 수행되도 원격 저장소에 바로 저장하거나 수정하지 않습니다. Git에서 원격 저장소에 저장하는 방식은, 먼저 커밋을 통해 로컬에 변경사항을 저장하고(git commit) 푸쉬를 통해 원격 저장소에 변경 사항을 반영시키는(git push) 2단계로 나뉘어져 있습니다. 푸쉬하는 예제는 1.3.5에 있습니다.

또한 log 명령어를 통해서 커밋 메시지 이력을 확인할 수 있습니다.

$ git log
commit df0a62f3f091e53ffa799309b3e32c27b0b38eb4
Author: Michael Hartl <michael@michaelhartl.com>
Date:   Thu Oct 15 11:36:21 2009 -0700

  Initialize repository

git log를 종료하려면 q 키를 눌러주세요.

1.3.3 Git의 장점

아직까지 버전 관리 시스템을 사용하는 이유가 잘 이해되지 않는 분들도 있을 거라고 생각합니다. 예를 하나 들어보겠습니다. 여러분이 실수로 app/controllers/ 디렉토리를 지웠다고 생각해보세요.

$ ls app/controllers/
application_controller.rb
$ rm -rf app/controllers/
$ ls app/controllers/
ls: app/controllers/: No such file or directory

여러분은 Unix의 ls 명령어를 실행시켜 app/controller/ 디렉토리의 파일들을 확인했습니다. 그 다음 실수로 rm 명령어를 실행시켰습니다. 여기서 -rf란 recursive(서브 디렉토리를 비롯한 모든 파일을 삭제), force(삭제할 지 여부를 묻지 않고 삭제함) 옵션을 의미합니다.

우선 현재의 상태를 확인해보겠습니다.

$ git status
# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       deleted:    app/controllers/application_controller.rb
#
no changes added to commit (use "git add" and/or "git commit -a")

이를 통해 파일이 하나 삭제된 걸 볼 수 있습니다. 하지만 삭제는 오직 '작업 트리'에서만 이루어 졌고 아직 커밋이 되지 않은 상태입니다. 즉 바로 이전의 커밋을 checkout 명령어로 체크아웃하면 삭제된 파일을 쉽게 복원할 수 있습니다. 여기선 마지막 커밋 이후의 변경사항을 모두 강제적으로 덮어써서 되돌리기 위해서 -f 옵션을 사용했습니다.

$ git checkout -f
$ git status
# On branch master
nothing to commit (working directory clean)
$ ls app/controllers/
application_controller.rb

삭제된 디렉토리가 복구된 걸 확인할 수 있습니다. 이 얼마나 듬직합니까!

1.3.4GitHub

Git를 사용해 어플리케이션을 버전관리 시스템에 추가했으니 이번엔 GitHub에 소스코드를 업로드 해보겠습니다. GitHub는 Git 저장소를 보관할 수 있는 공간을 제공하고, 다른 프로그래머와 협업을 용이하게 만들어주는 웹서비스입니다.굳이 GitHub 저장소를 추가로 만드는 데는 두 가지 이유가 있습니다. 먼저 소스코드와 변경 이력 전부를 백업하기 위해서 입니다. 두번째는 다른 프로그래머와 협업을 쉽게 하기 위해서입니다. 이 부분을 그냥 넘기셔도 무방합니다만 GitHub에 가입해두시면 다른 많은 오픈소스 프로젝트에 참여할 기회를 얻을 수 있습니다.

create_first_repository_4_0
그림 1.6 GitHub에 first app 저장소를 생성하기. (확대)

GitHub에는 다양한 과금 정책이 준비되어있습니다만 오픈소스 코드에 대해서는 무료로 사용할 수 있습니다. 처음 사용하신다면 GitHub 무료 계정을 만들어주세요(우선 GitHub SSh 키 생성 튜토리얼을 읽고 따라할 필요가 있습니다.) 계정을 만드셨으면 Create repository를 클릭해 그림 1.6과 같이 생성폼을 채워주시기 바랍니다. (이 때 README 파일을 사용해 저장소를 초기화하는 옵션은 체크하지 마시기 바랍니다. rails new 명령어를 실행시키면 README 파일은 자동적으로 생성됩니다.) 저장소가 만들어졌으면 이제 아래 명령어를 실행해 어플리케이션을 푸쉬합니다.

$ git remote add origin https://github.com/<username>/first_app.git
$ git push -u origin master

앞의 명령어는 현재 사용중인 메인 브렌치(master)를 "origin"으로 GitHub에 추가합니다. 그리고 두번째 명령어를 통해 GitHub 실제로 푸쉬합니다(-u 옵션은 신경쓰지 않으셔도 됩니다만, 궁금하신 분은 "git set upstream"을 검색해보시기 바랍니다). 이 때 <username>은 여러분의 GitHub 계정명으로 바꾸셔야 합니다. 예를 들어 제 경우엔 아래와 같이 실행합니다.

$ git remote add origin https://github.com/mhartl/first_app.git

이 명령어를 실행하면 GitHub에 first app의 저장소 페이지가 만들어집니다. 이 페이지에서 파일을 보거나 커밋 이력을 출력하는 등 저장소에 관련된 여러가지 기능을 사용할 수 있습니다.

github_repository_page_4_0
그림 1.7 GitHub의 저장소 페이지. (확대)

또한 GitHub은 그래픽 인터페이스 어플리케이션도 제공하고 있습니다. GUI가 더 익숙한 분은 GitHub for WindowsGitHub for MAC을 참조해주세요(Linux용 GitHub는 아직 Git밖에 없는 것 같습니다.)

1.3.5 브랜치(branch), 변경(edit), 커밋(commit), 병합(merge)

1.3.4 절을 따라해오셨다면 GitHub 저장소의 메인 페이지에 README 파일 내용이 나타나는 걸 알 수 있습니다. 이 튜토리얼에서는 rails 명령어를 사용해서 어플리케이션을 생성했기 때문에 이미 README 파일이 저장소에 포함되어있습니다. README 파일의 확장자는 .rdoc이며 GitHub는 이에 따라 문서를 보기 좋게 만들어 줍니다. 하지만 README엔 Rails 프레임워크 자체에 관한 내용이 포함되어 있어, 프로그래밍 중인 어플리케이션을 설명하는 데는 적합하지 않습니다. 이 절에서는 README의 내용을 수정하고 프로젝트에 관한 내용을 추가하도록 하겠습니다. 이 과정에서 제가 추천드렸던 Git를 사용해 branch, edit, commit, merge를 수행하는 워크플로를 처음으로 경험할 수 있습니다.

rails_readme_4_0
그림 1.8 GitHub에 표시되는 기본 README 파일.(확대)

브랜치(Branch)

Git에서는 브랜치(branch)를 아주 간단히 만들 수 있습니다.브렌치에 부모 저장소의 파일들을 복사해 원본 파일들을 수정하지 않고도 코드를 수정할 수 있게 해줍니다. 대부분 부모 저장소는 마스터(master) 브랜치가 되며, checkout 명령에 -b 옵션을 사용해 새로운 토픽 브랜치를 만들 수 있습니다.

$ git checkout -b modify-README
Switched to a new branch 'modify-README'
$ git branch
master
* modify-README

git branch 명령어는 로컬에 있는 브랜치 일람을 출력합니다. * 표시는 현재 작업중인 브랜치를 의미합니다. 첫번째 명령어 git checkout -b modify-README 명령어는 브랜치를 새로 만들고 만들어진 브랜치로 이동시켜줍니다. modify-README 브랜치 앞에 있는 별표를 통해 현재 작업중인 브랜치가 여기임을 알 수 있습니다(참고로 1.3 절에서 checkout에 co라는 별칭을 붙여줬다면 git co -b modify-README 명령어를 사용할 수 있습니다.)

브랜치의 진정한 가치는 다른 프로그래머와 협업을 하면서 빛이 납니다만 19 이 튜토리얼에서 처럼 혼자서 프로그래밍하는 데도 큰 도움을 줍니다. 토픽 브랜치를 수정해도 마스터 브랜치는 영향을 받지 않습니다. 심지어 토픽 브랜치의 내용이 엉망진창이 돼버렸을지언정 마스터 브랜치로 체크아웃하고 토픽 브랜치를 지워버리면 그만입니다. 자세한 내용은 Git 파트 마지막에 하도록 하겠습니다.

지금과 같이 작은 수정을 위해 굳이 브랜치를 새로 만들 필요는 없습니다만, 좋은 습관은 미리미리 들이는 게 좋습니다.

변경 (Edit)

토픽 브랜치를 만들었으니 이제 README의 내용을 개선해보겠습니다. 저는 Rails 어플리케이션 생성시 자동으로 사용되는 RDoc 포맷보다 마크다운(Markdown)이라는 마크업 언어를 선호합니다. 확장자를 .md로 바꿔 GitHub에서 올려두면 마크다운 문법에 따라 자동적으로 문서를 생성해줍니다. 따라서 Git의 파일 이동 명령어 mv를 사용해 파일 이름을 변경하고, 리스트 1.8과 같이 파일을 수정하도록 하겠습니다.

$ git mv README.rdoc README.md
$ subl README.md
리스트 1.8 새로운 README 파일(README.md).
# Ruby on Rails 튜토리얼:샘플 어플리케이션

This is the first application for the
[*Ruby on Rails Tutorial*](http://tutorial.rails.kr/)
by [Michael Hartl](http://michaelhartl.com/).

커밋 (commit)

수정을 했으니 이번엔 브랜치의 상태를 확인해보겠습니다.

$ git status
# On branch modify-README
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    README.rdoc -> README.md
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   README.md
#

이 시점에서 1.3.2 절에서 배운대로 git add . 명령어를 사용할 수도 있지만, commit 명령어에 -a 옵션을 사용해 현재 존재하는 모든 파일에 대해서 변경된 사항들만 커밋할 수도 있습니다. 이 옵션은 앞으로 자주 사용하게 될 것입니다. (git mv를 통해서 생성된(이동된) 파일은 버전 관리 대상에 자동적으로 포함됩니다.)

$ git commit -a -m "Improve the README file"
2 files changed, 5 insertions(+), 243 deletions(-)
delete mode 100644 README.rdoc
create mode 100644 README.md

-a 옵션을 사용할 때 주의하셔야될 부분이 있습니다. 마지막 커밋 이후 만들어진 새로운 파일 있다면 먼저 git add 명령어를 사용해 해당 파일을 버전 관리 대상에 포함시켜야만 합니다.

커밋 메시지는 현재 시제로 작성해주세요. Git에선 단일 패치가 아니라 일련의 패치들을 커밋하게 되므로 커밋 메시지에는 이 커밋이 무엇을 했었는지보다는 무엇을 하는지를 나타내도록 하는 편이 좋습니다. 또한 현재 시제로 작성된 커밋 메시지는 Git 명령어가 생성하는 커밋 메시지와도 잘 어울립니다. 더 자세한 사항은 GitHub에 올라온 '최신 커밋 스타일(Shiny new commit styles)'를 참조하시기 바랍니다.

병합 (Merge)

파일 수정이 끝났으니 이제 마스터 브랜치에 이 수정 사항을 병합(merge)해보겠습니다.

$ git checkout master
Switched to branch 'master'
$ git merge modify-README
Updating 34f06b7..2c92bef
Fast forward
README.rdoc     |  243 --------------------------------------------------
README.md       |    5 +
2 files changed, 5 insertions(+), 243 deletions(-)
delete mode 100644 README.rdoc
create mode 100644 README.md

Git의 출력을 보면 34f06b7을 포함한 문자열이 보입니다. 이는 Git 내부적으로 저장소를 나타내는 데 사용되는 해시입니다. 이 문자열을 제외한 나머지 출력은 위와 비슷한 것입니다.

변경을 병합한 후 git branch -d를 실행해 토픽 브렌치를 제거해주면 끝입니다.

$ git branch -d modify-README
Deleted branch modify-README (was 2c92bef).

토픽 브렌치를 삭제하지 않아도 괜찮습니다. 실제로 토픽 브랜치를 삭제하지 않고 놔두는 경우도 자주 있습니다. 토픽 브랜치를 삭제 하지 않고 마스터 브랜치와 토픽 브랜치를 왔다갔다 하며 적절한 타이밍에 병합 할 수도 있습니다.

위에서 언급한 대로 git branch -D 명령어를 사용해 토픽 브랜치의 변경사항을 되돌릴 수도 있습니다.

# 설명을 위한 부분입니다. 브랜치가 엉망이 된 상태가 아니면 실행하지 마세요.
$ git checkout -b topic-branch
$ <브랜치를 엉망으로 만들어보세요>
$ git add .
$ git commit -a -m "Major screw up"
$ git checkout master
$ git branch -D topic-branch

-D 옵션은 -d 옵션과 달리 병합이 이루어지지 않았더라도 브랜치를 삭제합니다.

푸시(push)

README 작업이 끝났으니 이제 변경사항을 GitHub에 push 해서 반영해보도록하겠습니다. 이미 앞선 1.3.4 절에서 한 번 푸시를 했기 때문에 git push 명령어를 실행할 때마다 origin master를 붙여주지 않아도 됩니다.

$ git push

앞서 이야기한대로 GitHub에서 자동저으로 마크다운 문서를 생성해줍니다.

new_readme_4_0
그림 1.9 마크다운으로 기술된 개선된 README 파일(확대)

1.4 배포

아직 이른 단계이긴 하지만 (비어있는) Rails 어플리케이션을 실제로 배포해보도록 하겠습니다. 배포를 반드시해야하는 건 아닙니다만 자주 배포함으로써 이후에 생길 문제들을 미리 파악할 수 있습니다. 프로그래밍 과정에서 배포 작업을 하지 않고 어플리케이션을 완성해 나간다면, 서비스를 선보일 때 예상치 못한 문제들로 골머리를 썩을 지도 모릅니다.

이전엔 Rails 어플리케이션을 배포한다는 게 상당히 어려운 일이었습니다. 하지만 요 몇년간 Rails 배포를 둘러싼 환경들이 매우 좋아졌으면, 지금은 몇 가지 훌륭한 선택지들이 존재합니다. 대표적으로 Phusion Passenger(Apache와 Nginx2321 서버용 모듈)를 통한 웹호스팅과 가상 서버 호스팅을 비롯해 배포 전문 서비스인 Engine Yard, Rails Machine 그리고 클래우드 서비스를 제공하는 Engine Yard Cloud, Heroku를 들 수 있습니다.

제가 추천하는 Heroku는 Rails를 비롯한 웹 어플리케이션을 호스팅하는데 최적화된 플랫폼입니다. Git를 사용하고 있다면 Heroku를 통한 배포는 아주 쉽습니다.(Git를 설치한 또 다른 이유이기도 합니다. Git를 아직 설치하지 않으신 분들은 1.3 절을 읽어주세요). 이번 장의 마지막 부분에서는 Heroku를 통해 첫 어플리케이션을 배포해보겠습니다.

1.4.1 Heroku 셋업

Heroku에서는 PostgreSQL 데이터베이스를 사용합니다("post-gres-cue-ell" 혹은 줄여서 "Postgres"라고 발음합니다). 이를 위해 production 환경에 pg gem을 추가해 Rails에서 Postgres를 사용할 수 있도록 합니다.

group :production do
  gem 'pg', '0.15.1'
  gem 'rails_12factor', '0.0.2'
end

rails_12factor gem이 추가된 데 주목해주시기 바랍니다. 이 gem은 이미지, 스타일시트와 같은 정적 애셋을 Heroku에서 서비스하기 위해 사용합니다.

1.2.4 절에서도 설명했습니다만 사용할 Ruby 버전을 명시하는 것도 좋은 습관입니다.

ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0

(사용할 RVM gemset도 다음 행에 지정합니다. 필요한 경우엔 Ruby 버전을 1.9.3으로 지정해주시기 바랍니다. 이 책과 약간 달라집니다만 특별한 문제는 없습니다.) 위의 변경사항을 리스트 1.5 Gemfile에 적용하면 리스트 1.9와 같아집니다.

리스트 1.9 필요한 gem을 추가하고 Ruby 버전을 명시한 Gemfile
source 'https://rubygems.org'
ruby '2.0.0'
#ruby-gemset=railstutorial_rails_4_0

gem 'rails', '4.0.0'

group :development do
  gem 'sqlite3', '1.3.7'
end

gem 'sass-rails', '4.0.0'
gem 'uglifier', '2.1.1'
gem 'coffee-rails', '4.0.0'
gem 'jquery-rails', '2.2.1'
gem 'turbolinks', '1.1.1'
gem 'jbuilder', '1.0.2'

group :doc do
  gem 'sdoc', '0.3.20', require: false
end

group :production do
  gem 'pg', '0.15.1'
  gem 'rails_12factor', '0.0.2'
end

이 때 bundle install로 gem을 설치할 때는 새로운 옵션을 사용합니다.

$ bundle install --without production

--without production 옵션을 사용하면 pgrails_12factor 같은 production 환경에서 사용하는 gem을 로컬에 설치하지 않습니다(설치 과정에서 Bundler에서 readline에 관련된 에러가 출력된다면 Gemfilegem 'rb-readline'를 추가해주세요.) 바로 위에서 추가한 gem들은 production 환경에서만 사용되기 때문에 지금 'bundle install'을 실행한 데도 실제로는 어떠한 gem도 로컬에 설치하지 않습니다. 그럼에도 지금 이 명령어를 실행시키는 건 pg, rails_12factor gem과 어플리케이션에서 사용하는 Ruby의 버전을 Gemfile.lock 파일에 기록하기 위해서입니다. 아래 명령어를 실행해 변경 사항을 커밋합니다.

$ git commit -a -m "Update Gemfile.lock for Heroku"

다음으로 Heroku 계정을 만들고 설정하겠습니다. 먼저 Heroku에 사용자 등록을 합니다. 계정을 만들고 나면 사용자 인증을 위해 발송된 메일을 확인하고, Heroku Toolbelt를 설치합니다22. 다음 명령어를 실행해 명령행에서 Heroku에 로그인합니다(명령어를 사용할 수 없는 경우엔 터미널 프로그램을 재실행시켜주세요).

$ heroku login

마지막으로 Rails 어플리케이션 디렉토리로 이동해서 heroku 명령어를 실행시킵니다. 이 명령어는 어플리케이션을 실행할 수 있는 공간을 Heroku 서버에 만들어줍니다.

리스트 1.10 Heroku에서 실행되는 새로운 어플리케이션 만들기.
$ cd ~/rails_projects/first_app
$ heroku create
Created http://stormy-cloud-5881.herokuapp.com/ |
git@heroku.com:stormy-cloud-5881.herokuapp.com
Git remote heroku added

heroku 명령어를 실행하면 어플리케이션에 접속할 수 있는 전용 서브 도메인을 만들어주며, 바로 브라우저를 통해 확인할 수 있습니다. 아직은 서버에 아무것도 없으니 바로 어플리케이션을 이 서버를 통해 배포해보겠습니다.

1.4.2 Heroku에 배포 (1)

먼저 어플리케이션을 배포하기 위해 Git를 사용해 현재 저장소를 Heroku에 푸시 합니다.

$ git push heroku master

1.4.3 Heroku에 배포 (2)

다음으로 할 일은 없습니다! 이걸로 끝입니다(그림 1.10). 배포된 어플리케이션을 확인하기 위해 앞서 heroku create 명령어를 실행할 때 출력된 주소로 접속해주세요(이 때 리스트 1.10에 나온 주소로 접속하시면 안 됩니다. 직접 명령어를 실행해서 출력된 주소로 접속해주세요). 아니면 어플리케이션이 배포된 주소로 브라우저를 열어주는 heroku 명령어를 사용할 수도 있습니다.

$ heroku open

하지만 에러 페이지가 출력될 것입니다. 몇 가지 기술적인 문제로 Rails 4.0 어플리케이션을 바로 Heroku에 배포할 시 정상적으로 작동하지 않습니다. 다행히 루트 라우트를 추가하면 이 에러 페이지는 더 이상 출력되지 않습니다.

heroku_app_4_0
그림 1.10Heroku에서 실행되고 있는 Rails 튜토리얼의 첫 어플리케이션(확대)

Heroku에 배포가 성공적으로 끝나면 아래와 같은 우아한 인터페이스를 통해 어플리케이션을 관리할 수 있습니다.

heroku_info_4_0
그림 1.11 우아한 Heroku의 인터페이스. (확대)

1.4.4Heroku 명령어

여러가지 Heroku 명령어가 있지만 여기에서는 간단히 중요한 몇가지만 다루겠습니다. 우선 아래의 명령어를 실행해 어플리케이션의 이름을 변경해보죠.

$ heroku rename railstutorial

이 때 여러분은 railstutorial이라는 이름을 사용할 수 없습니다. 이 이름은 이미 제가 사용중이므로 다른 이름을 사용해야만 합니다. 지금 시점에선 Heroku에서 자동으로 생성된 이름을 사용하셔도 무방합니다. 실제로 이름을 바꿔보고 싶으신 분은 보안을 위해 아래의 예들과 같이 뜻이 없고 무작위로 만들어진 듯한 이름을 사용하시기 바랍니다.

hwpcbmze.herokuapp.com
seyjhflo.herokuapp.com
jhyicevg.herokuapp.com

이러한 도메인 이름을 사용하면 여러분이 이 주소를 직접 알려줘야만 어플리케이션에 접속할 수 있습니다. (잠시 Ruby의 강력함을 보여드리기 위해 서브 도메인을 무작위로 생성해주는 코드를 만들어보겠습니다.

('a'..'z').to_a.shuffle[0..7].join

아주 간단하죠.)

Heroku에서는 서브 도메인 뿐만 아니라 여러분이 따로 구매하신 도메인을 사용할 수도 있습니다(이 Ruby on Rails 튜토리얼 사이트도 바로 Heroku 서버에 있습니다. 여러분이 이 책을 온라인으로 보고 계신다면 Heroku를 이용하고 있는 사이트를 보고 계신 겁니다!) 도메인을 비롯해 Heroku에 관련된 추가적인 정보는 Heroku 문서를 참조하시기 바랍니다.

1.5 결론

첫 장에서 Ruby와 Rails 설치, 개발 환경 구축, 버전 관리, 배포 등 다양한 주제를 다뤘습니다. 지금까지 과정을 다른 사람들과 공유하고 싶으시면 Twitter나 Facebook에 자유롭게 올려주세요.

 

이제 남은 건 Rails에 대해서 공부하는 일입니다. 그럼 시작해보죠.

  1. URI은 Uniform Resource Identifier의 줄임말입니다. 이보다 좀 덜 사용되는 URL은 Uniform Resource Locator의 줄임말입니다. 실질적으로 URL이란 브라우저의 주소창에 보이는 바로 그 주소라고 생각하셔도 됩니다.
  2. http://tryruby.org/ 
  3. http://railsforzombies.org/ 
  4. http://railstutorial.org/screencasts 
  5. Rails 튜토리얼을 읽는 동안 다른 절로 연결된 링크를 편리하게 사용할 수 있습니다. 잠시 다른 절로 이동했다면 다시 원래 읽던 부분으로 돌아와야겠죠. 사이트에서 읽고 계시다면 브라우져의 '뒤로'버턴을 누르시면 됩니다. Adobe Reader이나 OS X의 '미리보기'으로 PDF 판을 읽고 계시다면 아래의 방법을 사용할 수 있습니다. Adobe Reader에서는 문서 화면에서 오른쪽 버튼을 눌러 'Previous View'를 클릭합니다. OS X 미리보기에서는 이동 > 이전항목 메뉴를 사용합니다.
  6. 많은 사람들이 sudo 명령어를 관리자(root) 권한으로 프로그램을 실행시키거나 "superuser do"의 줄임말이라고 오해하고 있습니다. 사실 sudosu 명령어와 영어의 "do"를 합성한 단어입니다. 여기서 su 명령어는 "substitute user"의 줄임말로 사용자를 변경한다는 의미입니다. man su 명령어를 통해 이를 확인해보실 수 있습니다. 어원에 따르면 "SOO-doo"라는 발음이 옳습니다만("do"는 "doo"라고 발음하니까요) "SOO-doh"라는 발음도 많이 사용됩니다.
  7. http://railstutorial.org/help 
  8. https://github.com/perfectionist/sample_project/wiki 
  9. 현재 Sublime Text 3은 베타판입니다. Sublime Text 2를 사용하시는 걸 추천합니다.
  10. vi는 Unix라는 무기고에서 가장 오래되고 강력한 무기입니다. 또한 Vim은 "vi improved"의 줄임말입니다.
  11. https://github.com/mhartl/rails_tutorial_sublime_text 
  12. https://developer.apple.com/downloads/ 
  13. http://strandcode.com/2013/07/11/ruby-version-manager-rvm-overview-for-rails-newbs/ 
  14. 이 과정은 Rails gem의 버전을 변경했을 때만 필요합니다. 보통 Rails 인스톨러를 사용했을 때 Rails gem의 버전을 바꿀 필요가 생깁니다만, 그렇지 않더라도 이 과정을 수행한다고 문제가 생기는 건 아닙니다.
  15. 웹 서버는 일반적으로 80번 포트에서 실행되지만 이 포트를 사용하기 위해서는 특별한 권한이 필요합니다. 따라서 Rails의 development 환겨엥서는 비교적 제한이 적은 높은 번호의 포트를 사용합니다.
  16. 기본적으로 GUI 에디터를 사용해도 터미널을 계속할 수 있도록 만들어져있습니다.하지만 이런 경우엔 Git에서는 커밋 메시지를 아무것도 입력하지 않은 채 에디터를 닫아버렸다고 인식해버립니다.따라서 에디터에서 커밋 메시지를 수정한 다음에 다시 터미널을 사용할 수 있도록 해야만 정상적으로 에디터를 통해 커밋 메시지를 입력할 수 있습니다. 이를 위해 subl이나 gvim에 옵션을 지정할 필요가 있습니다.(무슨 뜻인지 이해가 되지 않으신다면 무시하셔도 괜찮습니다.)
  17. .gitignore 파일이 보이지 않는다면 먼저 파일 뷰어에서 숨겨진 파일이 보이도록 설정할 필요가 있습니다.
  18. git status 실행시에 필요하지 않은 파일이 있다면 리스트 1.7 .gitignore 파일에 추가해주시면 됩니다.
  19. 자세한 내용은 Pro Git의'Git 브랜치'를 참조해주세요.
  20. 샘플 어플리케이션에서 신경 쓰실 필요는 없습니다. 아직 프로그래밍 중인 Web 어플리케이션을 공개하는 게 꺼려지신다면 몇 가지 방법이 있습니다.1.4.4 절의 내용도 그 중 하나입니다.
  21. “Engine X"로 발음합니다.
  22. https://toolbelt.heroku.com/