Ruby on Rails Tutorial

Learn Rails by Example

Michael Hartl

Contents

  1. Chapter 1 From zero to deploy
    1. 1.1 Introduction
      1. 1.1.1 Comments for various readers
      2. 1.1.2 “Scaling” Rails
      3. 1.1.3 Conventions in this book
    2. 1.2 Up and running
      1. 1.2.1 Development environments
        1. IDEs
        2. Text editors and command lines
        3. Browsers
        4. A note about tools
      2. 1.2.2 Ruby, RubyGems, Rails, and Git
        1. Rails Installer (Windows)
        2. Install Git
        3. Install Ruby
        4. Install RubyGems
        5. Install Rails
      3. 1.2.3 The first application
      4. 1.2.4 Bundler
      5. 1.2.5 rails server
      6. 1.2.6 Model-view-controller (MVC)
    3. 1.3 Version control with Git
      1. 1.3.1 Installation and setup
        1. First-time system setup
        2. First-time repository setup
      2. 1.3.2 Adding and committing
      3. 1.3.3 What good does Git do you?
      4. 1.3.4 GitHub
      5. 1.3.5 Branch, edit, commit, merge
        1. Branch
        2. Edit
        3. Commit
        4. Merge
        5. Push
    4. 1.4 Deploying
      1. 1.4.1 Heroku setup
      2. 1.4.2 Heroku deployment, step one
      3. 1.4.3 Heroku deployment, step two
      4. 1.4.4 Heroku commands
    5. 1.5 Conclusion
  2. Chapter 2 A demo app
    1. 2.1 Planning the application
      1. 2.1.1 Modeling users
      2. 2.1.2 Modeling microposts
    2. 2.2 The Users resource
      1. 2.2.1 A user tour
      2. 2.2.2 MVC in action
      3. 2.2.3 Weaknesses of this Users resource
    3. 2.3 The Microposts resource
      1. 2.3.1 A micropost microtour
      2. 2.3.2 Putting the micro in microposts
      3. 2.3.3 A user has_many microposts
      4. 2.3.4 Inheritance hierarchies
      5. 2.3.5 Deploying the demo app
    4. 2.4 Conclusion
  3. Chapter 3 Mostly static pages
    1. 3.1 Static pages
      1. 3.1.1 Truly static pages
      2. 3.1.2 Static pages with Rails
    2. 3.2 Our first tests
      1. 3.2.1 Testing tools
        1. Autotest
      2. 3.2.2 TDD: Red, Green, Refactor
        1. Spork
        2. Red
        3. Green
        4. Refactor
    3. 3.3 Slightly dynamic pages
      1. 3.3.1 Testing a title change
      2. 3.3.2 Passing title tests
      3. 3.3.3 Instance variables and Embedded Ruby
      4. 3.3.4 Eliminating duplication with layouts
    4. 3.4 Conclusion
    5. 3.5 Exercises
  4. Chapter 4 Rails-flavored Ruby
    1. 4.1 Motivation
      1. 4.1.1 A title helper
      2. 4.1.2 Cascading Style Sheets
    2. 4.2 Strings and methods
      1. 4.2.1 Comments
      2. 4.2.2 Strings
        1. Printing
        2. Single-quoted strings
      3. 4.2.3 Objects and message passing
      4. 4.2.4 Method definitions
      5. 4.2.5 Back to the title helper
    3. 4.3 Other data structures
      1. 4.3.1 Arrays and ranges
      2. 4.3.2 Blocks
      3. 4.3.3 Hashes and symbols
      4. 4.3.4 CSS revisited
    4. 4.4 Ruby classes
      1. 4.4.1 Constructors
      2. 4.4.2 Class inheritance
      3. 4.4.3 Modifying built-in classes
      4. 4.4.4 A controller class
      5. 4.4.5 A user class
    5. 4.5 Exercises
  5. Chapter 5 Filling in the layout
    1. 5.1 Adding some structure
      1. 5.1.1 Site navigation
      2. 5.1.2 Custom CSS
      3. 5.1.3 Partials
    2. 5.2 Layout links
      1. 5.2.1 Integration tests
      2. 5.2.2 Rails routes
      3. 5.2.3 Named routes
    3. 5.3 User signup: A first step
      1. 5.3.1 Users controller
      2. 5.3.2 Signup URL
    4. 5.4 Conclusion
    5. 5.5 Exercises
  6. Chapter 6 Modeling and viewing users, part I
    1. 6.1 User model
      1. 6.1.1 Database migrations
      2. 6.1.2 The model file
        1. Model annotation
        2. Accessible attributes
      3. 6.1.3 Creating user objects
      4. 6.1.4 Finding user objects
      5. 6.1.5 Updating user objects
    2. 6.2 User validations
      1. 6.2.1 Validating presence
      2. 6.2.2 Length validation
      3. 6.2.3 Format validation
      4. 6.2.4 Uniqueness validation
        1. The uniqueness caveat
    3. 6.3 Viewing users
      1. 6.3.1 Debug and Rails environments
      2. 6.3.2 User model, view, controller
      3. 6.3.3 A Users resource
        1. params in debug
    4. 6.4 Conclusion
    5. 6.5 Exercises
  7. Chapter 7 Modeling and viewing users, part II
    1. 7.1 Insecure passwords
      1. 7.1.1 Password validations
      2. 7.1.2 A password migration
      3. 7.1.3 An Active Record callback
    2. 7.2 Secure passwords
      1. 7.2.1 A secure password test
      2. 7.2.2 Some secure password theory
      3. 7.2.3 Implementing has_password?
      4. 7.2.4 An authenticate method
    3. 7.3 Better user views
      1. 7.3.1 Testing the user show page (with factories)
      2. 7.3.2 A name and a Gravatar
        1. A Gravatar helper
      3. 7.3.3 A user sidebar
    4. 7.4 Conclusion
      1. 7.4.1 Git commit
      2. 7.4.2 Heroku deploy
    5. 7.5 Exercises
  8. Chapter 8 Sign up
    1. 8.1 Signup form
      1. 8.1.1 Using form_for
      2. 8.1.2 The form HTML
    2. 8.2 Signup failure
      1. 8.2.1 Testing failure
      2. 8.2.2 A working form
      3. 8.2.3 Signup error messages
      4. 8.2.4 Filtering parameter logging
    3. 8.3 Signup success
      1. 8.3.1 Testing success
      2. 8.3.2 The finished signup form
      3. 8.3.3 The flash
      4. 8.3.4 The first signup
    4. 8.4 RSpec integration tests
      1. 8.4.1 Integration tests with style
      2. 8.4.2 Users signup failure should not make a new user
      3. 8.4.3 Users signup success should make a new user
    5. 8.5 Conclusion
    6. 8.6 Exercises
  9. Chapter 9 Sign in, sign out
    1. 9.1 Sessions
      1. 9.1.1 Sessions controller
      2. 9.1.2 Signin form
    2. 9.2 Signin failure
      1. 9.2.1 Reviewing form submission
      2. 9.2.2 Failed signin (test and code)
    3. 9.3 Signin success
      1. 9.3.1 The completed create action
      2. 9.3.2 Remember me
      3. 9.3.3 Current user
    4. 9.4 Signing out
      1. 9.4.1 Destroying sessions
      2. 9.4.2 Signin upon signup
      3. 9.4.3 Changing the layout links
      4. 9.4.4 Signin/out integration tests
    5. 9.5 Conclusion
    6. 9.6 Exercises
  10. Chapter 10 Updating, showing, and deleting users
    1. 10.1 Updating users
      1. 10.1.1 Edit form
      2. 10.1.2 Enabling edits
    2. 10.2 Protecting pages
      1. 10.2.1 Requiring signed-in users
      2. 10.2.2 Requiring the right user
      3. 10.2.3 Friendly forwarding
    3. 10.3 Showing users
      1. 10.3.1 User index
      2. 10.3.2 Sample users
      3. 10.3.3 Pagination
        1. Testing pagination
      4. 10.3.4 Partial refactoring
    4. 10.4 Destroying users
      1. 10.4.1 Administrative users
        1. Revisiting attr_accessible
      2. 10.4.2 The destroy action
    5. 10.5 Conclusion
    6. 10.6 Exercises
  11. Chapter 11 User microposts
    1. 11.1 A Micropost model
      1. 11.1.1 The basic model
        1. Accessible attribute
      2. 11.1.2 User/Micropost associations
      3. 11.1.3 Micropost refinements
        1. Default scope
        2. Dependent: destroy
      4. 11.1.4 Micropost validations
    2. 11.2 Showing microposts
      1. 11.2.1 Augmenting the user show page
      2. 11.2.2 Sample microposts
    3. 11.3 Manipulating microposts
      1. 11.3.1 Access control
      2. 11.3.2 Creating microposts
      3. 11.3.3 A proto-feed
      4. 11.3.4 Destroying microposts
      5. 11.3.5 Testing the new home page
    4. 11.4 Conclusion
    5. 11.5 Exercises
  12. Chapter 12 Following users
    1. 12.1 The Relationship model
      1. 12.1.1 A problem with the data model (and a solution)
      2. 12.1.2 User/relationship associations
      3. 12.1.3 Validations
      4. 12.1.4 Following
      5. 12.1.5 Followers
    2. 12.2 A web interface for following and followers
      1. 12.2.1 Sample following data
      2. 12.2.2 Stats and a follow form
      3. 12.2.3 Following and followers pages
      4. 12.2.4 A working follow button the standard way
      5. 12.2.5 A working follow button with Ajax
    3. 12.3 The status feed
      1. 12.3.1 Motivation and strategy
      2. 12.3.2 A first feed implementation
      3. 12.3.3 Scopes, subselects, and a lambda
      4. 12.3.4 The new status feed
    4. 12.4 Conclusion
      1. 12.4.1 Extensions to the sample application
        1. Replies
        2. Messaging
        3. Follower notifications
        4. Password reminders
        5. Signup confirmation
        6. RSS feed
        7. REST API
        8. Search
      2. 12.4.2 Guide to further resources
    5. 12.5 Exercises
  13. Chapter 13 Rails 3.1
    1. 13.1 Upgrading the sample app
      1. 13.1.1 Installing and configuring Rails 3.1
      2. 13.1.2 Getting to Red
      3. 13.1.3 Minor issues
        1. will_paginate
        2. Pagination spec
      4. 13.1.4 Major differences
        1. Asset directories
        2. Prototype to jQuery
    2. 13.2 New features in Rails 3.1
      1. 13.2.1 Asset pipeline
      2. 13.2.2 Reversible migrations
      3. 13.2.3 Sass and CoffeeScript
    3. 13.3 Exercises

Foreword

My former company (CD Baby) was one of the first to loudly switch to Ruby on Rails, and then even more loudly switch back to PHP (Google me to read about the drama). This book by Michael Hartl came so highly recommended that I had to try it, and Ruby on Rails Tutorial is what I used to switch back to Rails again.

Though I’ve worked my way through many Rails books, this is the one that finally made me “get” it. Everything is done very much “the Rails way”—a way that felt very unnatural to me before, but now after doing this book finally feels natural. This is also the only Rails book that does test-driven development the entire time, an approach highly recommended by the experts but which has never been so clearly demonstrated before. Finally, by including Git, GitHub, and Heroku in the demo examples, the author really gives you a feel for what it’s like to do a real-world project. The tutorial’s code examples are not in isolation.

The linear narrative is such a great format. Personally, I powered through Rails Tutorial in three long days, doing all the examples and challenges at the end of each chapter. Do it from start to finish, without jumping around, and you’ll get the ultimate benefit.

Enjoy!

Derek Sivers (sivers.org)
Formerly: Founder, CD Baby
Currently: Founder, Thoughts Ltd.

Acknowledgments

Ruby on Rails Tutorial owes a lot to my previous Rails book, RailsSpace, and hence to my coauthor Aurelius Prochazka. I’d like to thank Aure both for the work he did on that book and for his support of this one. I’d also like to thank Debra Williams Cauley, my editor on both RailsSpace and Rails Tutorial; as long as she keeps taking me to baseball games, I’ll keep writing books for her.

I’d like to acknowledge a long list of Rubyists who have taught and inspired me over the years: David Heinemeier Hansson, Yehuda Katz, Carl Lerche, Jeremy Kemper, Xavier Noria, Ryan Bates, Geoffrey Grosenbach, Peter Cooper, Matt Aimonetti, Gregg Pollack, Wayne E. Seguin, Amy Hoy, Dave Chelimsky, Pat Maddox, Tom Preston-Werner, Chris Wanstrath, Chad Fowler, Josh Susser, Obie Fernandez, Ian McFarland, Steven Bristol, Wolfram Arnold, Alex Chaffee, Giles Bowkett, Evan Dorn, Long Nguyen, James Lindenbaum, Adam Wiggins, Tikhon Bernstam, Ron Evans, Wyatt Greene, Miles Forrest, the good people at Pivotal Labs, the Heroku gang, the thoughtbot guys, and the GitHub crew. Finally, many, many readers—far too many to list—have contributed a huge number of bug reports and suggestions during the writing of this book, and I gratefully acknowledge their help in making it as good as it can be.

About the author

Michael Hartl is a programmer, educator, and entrepreneur. Michael was coauthor of RailsSpace, a best-selling Rails tutorial book published in 2007, and was cofounder and lead developer of Insoshi, a popular social networking platform in Ruby on Rails. Previously, he taught theoretical and computational physics at the California Institute of Technology (Caltech), where he received the Lifetime Achievement Award for Excellence in Teaching. Michael is a graduate of Harvard College, has a Ph.D. in Physics from Caltech, and is an alumnus of the Y Combinator entrepreneur program.

Copyright and license

Ruby on Rails Tutorial: Learn Rails by Example. Copyright © 2010 by Michael Hartl. All source code in Ruby on Rails Tutorial is available under the MIT License and the Beerware License.

   Copyright (c) 2010 Michael Hartl

   Permission is hereby granted, free of charge, to any person
   obtaining a copy of this software and associated documentation
   files (the "Software"), to deal in the Software without
   restriction, including without limitation the rights to use,
   copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following
   conditions:

   The above copyright notice and this permission notice shall be
   included in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   OTHER DEALINGS IN THE SOFTWARE.
/*
 * ------------------------------------------------------------
 * "THE BEERWARE LICENSE" (Revision 42):
 * Michael Hartl wrote this code. As long as you retain this 
 * notice, you can do whatever you want with this stuff. If we
 * meet someday, and you think this stuff is worth it, you can
 * buy me a beer in return.
 * ------------------------------------------------------------
 */

Chapter 1 From zero to deploy

Welcome to Ruby on Rails Tutorial: Learn Rails by Example. The goal of this book is to be the best answer to the question, “If I want to learn web development with Ruby on Rails, where should I start?” By the time you finish Ruby on Rails Tutorial, you will have all the knowledge you need to develop and deploy your own custom web applications. You will also be ready to benefit from the many more advanced books, blogs, and screencasts that are part of the thriving Rails educational ecosystem. Finally, since Ruby on Rails Tutorial uses Rails 3, the knowledge you gain here will be fully up-to-date with the latest and greatest version of Rails.1

Ruby on Rails Tutorial follows essentially the same approach as my previous Rails book,2 teaching web development with Rails by building a substantial sample application from scratch. As Derek Sivers notes in the foreword, this book is structured as a linear narrative, designed to be read from start to finish. If you are used to skipping around in technical books, taking this linear approach might require some adjustment, but I suggest giving it a try. You can think of Ruby on Rails Tutorial as a video game where you are the main character, and where you level up as a Rails developer in each chapter. (The exercises are the minibosses.)

In this first chapter, we’ll get started with Ruby on Rails by installing all the necessary software and by setting up our development environment (Section 1.2). We’ll then create our first Rails application, called (appropriately enough) first_app. Rails Tutorial emphasizes good software development practices, so immediately after creating our fresh new Rails project we’ll put it under version control with Git (Section 1.3). And, believe it or not, in this chapter we’ll even put our first app on the wider web by deploying it to production (Section 1.4).

In Chapter 2, we’ll make a second project, whose purpose will be to demonstrate the basic workings of a Rails application. To get up and running quickly, we’ll build this demo app (called demo_app) using scaffolding (Box 1.1) to generate code; since this code is both ugly and complex, Chapter 2 will focus on interacting with the demo app through its URLs3 using a web browser.

In Chapter 3, we’ll create a sample application (called sample_app), this time writing all the code from scratch. We’ll develop the sample app using test-driven development (TDD), getting started in Chapter 3 by creating static pages and then adding a little dynamic content. We’ll take a quick detour in Chapter 4 to learn a little about the Ruby language underlying Rails. Then, in Chapter 5 through Chapter 10, we’ll complete the foundation for the sample application by making a site layout, a user data model, and a full registration and authentication system. Finally, in Chapter 11 and Chapter 12 we’ll add microblogging and social features to make a working example site.

The final sample application will bear more than a passing resemblance to a certain popular social microblogging site—a site which, coincidentally, was also originally written in Rails.4 Though of necessity our efforts will focus on this specific sample application, the emphasis throughout Rails Tutorial will be on general principles, so that you will have a solid foundation no matter what kinds of web applications you want to build.

1.1 Introduction

Since its debut in 2004, Ruby on Rails has rapidly become one of the most powerful and popular frameworks for building dynamic web applications. Rails users run the gamut from scrappy startups to huge companies: Posterous, UserVoice, 37signals, Shopify, GitHub, Scribd, Hulu, the Yellow Pages—the list of sites using Rails goes on and on. There are also many web development shops that specialize in Rails, such as ENTP, thoughtbot, Pivotal Labs, and Hashrocket, plus innumerable independent consultants, trainers, and contractors.

What makes Rails so great? First of all, Ruby on Rails is 100% open-source, available under the permissive MIT License, and as a result it also costs nothing to download and use. Rails also owes much of its success to its elegant and compact design; by exploiting the malleability of the underlying Ruby language, Rails effectively creates a domain-specific language for writing web applications. As a result, many common web programming tasks—such as generating HTML, making data models, and routing URLs—are easy with Rails, and the resulting application code is concise and readable.

Rails also adapts rapidly to new developments in web technology and framework design. For example, Rails was one of the first frameworks to fully digest and implement the REST architectural style for structuring web applications (which we’ll be learning about throughout this tutorial). And when other frameworks develop successful new techniques, Rails creator David Heinemeier Hansson and the Rails core team don’t hesitate to incorporate their ideas. Perhaps the most dramatic example is the merger of Rails and Merb, a rival Ruby web framework, so that Rails now benefits from Merb’s modular design, stable API, and improved performance. (Anyone who has attended a talk by Merb developer and Rails core team member Yehuda Katz can’t help but notice what an extremely good idea it was to bring the Merb team on board.)

Finally, Rails benefits from an unusually enthusiastic and diverse community. The results include hundreds of open-source contributors, well-attended conferences, a huge number of plugins and gems (self-contained solutions to specific problems such as pagination and image upload), a rich variety of informative blogs, and a cornucopia of discussion forums and IRC channels. The large number of Rails programmers also makes it easier to handle the inevitable application errors: the “Google the error message” algorithm nearly always produces a relevant blog post or discussion-forum thread.

1.1.1 Comments for various readers

Rails Tutorial contains integrated tutorials not only for Rails, but also for the underlying Ruby language, as well as for HTML, CSS, some JavaScript, and even a little SQL. This means that, no matter where you currently are in your knowledge of web development, by the time you finish this tutorial you will be ready for more advanced Rails resources, as well as for the more systematic treatments of the other subjects mentioned.

Rails derives much of its power from “magic”—that is, framework features (such as automatically inferring object attributes from database columns) that accomplish miracles but whose mechanisms can be rather mysterious. Ruby on Rails Tutorial is not designed to explain this magic—mainly because most Rails application developers never need to know what’s behind the curtain. (After all, Ruby itself is mostly written in the C programming language, but you don’t have to dig into the C source to use Ruby.) If you’re a confirmed pull-back-the-curtain kind of person, I recommend The Rails 3 Way by Obie Fernandez as a companion volume to Ruby on Rails Tutorial.

Although this book has no formal prerequisites, you should of course have at least some computer experience. If you’ve never even used a text editor before, it will be tough going, but with enough determination you can probably soldier through. If, on the other hand, your .emacs file is so complex it could make a grown man cry, there is still plenty of material to keep you challenged. Rails Tutorial is designed to teach Rails development no matter what your background is, but your path and reading experience will depend on your particular circumstances.

All readers: One common question when learning Rails is whether to learn Ruby first. The answer depends on your personal learning style. If you prefer to learn everything systematically from the ground up, then learning Ruby first might work well for you, and there are several book recommendations in this section to get you started. On the other hand, many beginning Rails developers are excited about making web applications, and would rather not slog through a 500-page book on pure Ruby before ever writing a single web page. Moreover, the subset of Ruby needed by Rails developers is different from what you’ll find in a pure-Ruby introduction, whereas Rails Tutorial focuses on exactly that subset. If your primary interest is making web applications, I recommend starting with Rails Tutorial and then reading a book on pure Ruby next. It’s not an all-or-nothing proposition, though: if you start reading Rails Tutorial and feel your (lack of) Ruby knowledge holding you back, feel free to switch to a Ruby book and come back when you feel ready. You might also consider getting a taste of Ruby by following a short online tutorial, such as can be found at http://www.ruby-lang.org/ or http://rubylearning.com/.

Another common question is whether to use tests from the start. As noted in the introduction, Rails Tutorial uses test-driven development (also called test-first development), which in my view is the best way to develop Rails applications, but it does introduce a substantial amount of overhead and complexity. If you find yourself getting bogged down by the tests, feel free to skip them on first reading.5 Indeed, some readers may find the inclusion of so many moving parts—such as tests, version control, and deployment—a bit overwhelming at first, and if you find yourself expending excessive energy on any of these steps, don’t hesitate to skip them. Although I have included only material I consider essential to developing professional-grade Rails applications, only the core application code is strictly necessary the first time through.

Inexperienced programmers (non-designers): Rails Tutorial doesn’t assume any background other than general computer knowledge, so if you have limited programming experience this book is a good place to start. Please bear in mind that it is only the first step on a long journey; web development has many moving parts, including HTML/CSS, JavaScript, databases (including SQL), version control, and deployment. This book contains short introductions to these subjects, but there is much more to learn.

Inexperienced programmers (designers): Your design skills give you a big leg up, since you probably already know HTML and CSS. After finishing this book you will be in an excellent position to work with existing Rails projects and possibly start some of your own. You may find the programming material challenging, but the Ruby language is unusually friendly to beginners, especially those with an artistic bent.

After finishing Ruby on Rails Tutorial, I recommend that newer programmers read Beginning Ruby by Peter Cooper, which shares the same basic instructional philosophy as Rails Tutorial. I also recommend The Ruby Way by Hal Fulton. Finally, to gain a deeper understanding of Rails I recommend The Rails 3 Way by Obie Fernandez.

Web applications, even relatively simple ones, are by their nature fairly complex. If you are completely new to web programming and find Rails Tutorial overwhelming, it could be that you’re not quite ready to make web applications yet. In that case, I’d suggest learning the basics of HTML and CSS and then giving Rails Tutorial another go. (Unfortunately, I don’t have a personal recommendation here, but Head First HTML looks promising, and one reader recommends CSS: The Missing Manual by David Sawyer McFarland.) You might also consider reading the first few chapters of Beginning Ruby, which starts with sample applications much smaller than a full-blown web app.

Experienced programmers new to web development: Your previous experience means you probably already understand ideas like classes, methods, data structures, etc., which is a big advantage. Be warned that if your background is in C/C++ or Java, you may find Ruby a bit of an odd duck, and it might take time to get used to it; just stick with it and eventually you’ll be fine. (Ruby even lets you put semicolons at the ends of lines if you miss them too much.) Rails Tutorial covers all the web-specific ideas you’ll need, so don’t worry if you don’t currently know a PUT from a POST.

Experienced web developers new to Rails: You have a great head start, especially if you have used a dynamic language such as PHP or (even better) Python. The basics of what we cover will likely be familiar, but test-driven development may be new to you, as may be the structured REST style favored by Rails. Ruby has its own idiosyncrasies, so those will likely be new, too.

Experienced Ruby programmers: The set of Ruby programmers who don’t know Rails is a small one nowadays, but if you are a member of this elite group you can fly through this book and then move on to The Rails 3 Way by Obie Fernandez.

Inexperienced Rails programmers: You’ve perhaps read some other tutorials and made a few small Rails apps yourself. Based on reader feedback, I’m confident that you can still get a lot out of this book. Among other things, the techniques here may be more up-to-date than the ones you picked up when you originally learned Rails.

Experienced Rails programmers: This book is unnecessary for you, but many experienced Rails developers have expressed surprise at how much they learned from this book, and you might enjoy seeing Rails from a different perspective.

After finishing Ruby on Rails Tutorial, I recommend that experienced (non-Ruby) programmers read The Well-Grounded Rubyist by David A. Black, which is an excellent in-depth discussion of Ruby from the ground up, or The Ruby Way by Hal Fulton, which is also fairly advanced but takes a more topical approach. Then move on to The Rails 3 Way to deepen your Rails expertise.

At the end of this process, no matter where you started, you will be ready for the more intermediate-to-advanced Rails resources. Here are some I particularly recommend:

  • Railscasts: Excellent free Rails screencasts
  • PeepCode, Pragmatic.tv, EnvyCasts: Excellent commercial screencasters
  • Rails Guides: Good topical and up-to-date Rails references. Rails Tutorial refers frequently to the Rails Guides for more in-depth treatment of specific topics.
  • Rails blogs: Too many to list, but there are tons of good ones.

1.1.2 “Scaling” Rails

Before moving on with the rest of the introduction, I’d like to take a moment to address the one issue that dogged the Rails framework the most in its early days: the supposed inability of Rails to “scale”—i.e., to handle large amounts of traffic. Part of this issue relied on a misconception; you scale a site, not a framework, and Rails, as awesome as it is, is only a framework. So the real question should have been, “Can a site built with Rails scale?” In any case, the question has now been definitively answered in the affirmative: some of the most heavily trafficked sites in the world use Rails. Actually doing the scaling is beyond the scope of just Rails, but rest assured that if your application ever needs to handle the load of Hulu or the Yellow Pages, Rails won’t stop you from taking over the world.

1.1.3 Conventions in this book

The conventions in this book are mostly self-explanatory; in this section, I’ll mention some that may not be.

Both the HTML and PDF editions of this book are full of links, both to internal sections (such as Section 1.2) and to external sites (such as the main Ruby on Rails download page).6

Many examples in this book use command-line commands. For simplicity, all command line examples use a Unix-style command line prompt (a dollar sign), as follows:

$ echo "hello, world"
hello, world

Windows users should understand that their systems will use the analogous angle prompt >:

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

On Unix systems, some commands should be executed with sudo, which stands for “substitute user do”. By default, a command executed with sudo is run as an administrative user, which has access to files and directories that normal users can’t touch, such as in this example from Section 1.2.2:

$ sudo ruby setup.rb

Most Unix/Linux/OS X systems require sudo by default, unless you are using Ruby Version Manager as suggested in Section 1.2.2.3; in this case, you would type this instead:

$ ruby setup.rb

Rails comes with lots of commands that can be run at the command line. For example, in Section 1.2.5 we’ll run a local development web server as follows:

$ rails server

As with the command-line prompt, Rails Tutorial uses the Unix convention for directory separators (i.e., a forward slash /). My Rails Tutorial sample application, for instance, lives in

/Users/mhartl/rails_projects/sample_app

On Windows, the analogous directory would be

C:\Sites\sample_app

The root directory for any given app is known as the Rails root, and henceforth all directories will be relative to this directory. (Note in particular that the “Rails root” is not the root directory for Rails itself.) For example, the config directory of my sample application is

/Users/mhartl/rails_projects/sample_app/config

The Rails root here is everything before config, i.e.,

/Users/mhartl/rails_projects/sample_app

For brevity, when referring to the file

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

I’ll omit the Rails root and simply write config/routes.rb.

Finally, Rails Tutorial often shows output from various programs (shell commands, version control status, Ruby programs, etc.). Because of the innumerable small differences between different computer systems, the output you see may not always agree exactly with what is shown in the text, but this is not cause for concern. In addition, some commands may produce errors depending on your system; rather than attempt the Sisyphean task of documenting all such errors in this tutorial, I will delegate to the “Google the error message” algorithm, which among other things is good practice for real-life software development.

1.2 Up and running

It’s time now to get going with a Ruby on Rails development environment and our first application. There is quite a bit of overhead here, especially if you don’t have extensive programming experience, so don’t get discouraged if it takes a while to get started. It’s not just you; every developer goes through it (often more than once), but rest assured that the effort will be richly rewarded.

1.2.1 Development environments

Considering various idiosyncratic customizations, there are probably as many development environments as there are Rails programmers, but there are at least two broad themes: text editor/command line environments, and integrated development environments (IDEs). Let’s consider the latter first.

IDEs

There is no shortage of Rails IDEs, including RadRails, RubyMine, and 3rd Rail. All are cross-platform, and I’ve heard good things about several of them. I encourage you to try them and see if they work for you, but I have a confession to make: I have never found an IDE that met all my Rails development needs—and for some projects I haven’t even been able to get them to work at all.

Text editors and command lines

What are we to use to develop Rails apps, if not some awesome all-in-one IDE? I’d guess the majority of Rails developers opt for the same solution I’ve chosen: use a text editor to edit text, and a command line to issue commands (Figure 1.1). Which combination you use depends on your tastes and your platform:

  • Macintosh OS X: Like many Rails developers, I prefer TextMate. Other options include Emacs and MacVim (launched with the command mvim), the excellent Macintosh version of Vim.7 I use iTerm for my command line terminal; others prefer the native Terminal app.
  • Linux: Your editor options are basically the same as OS X, minus TextMate. I’d recommend graphical Vim (gVim), gedit (with the GMate plugins), or Kate. As far as command lines go, you’re totally set: every Linux distribution comes with at least one command line terminal application (and often several).
  • Windows: Some promising editors on Windows include Vim, the E Text Editor, Komodo Edit, and Sublime Text. For a command line, I recommend using the command prompt that comes with Rails Installer (Section 1.2.2.1).

If you go with some flavor of Vim, be sure to tap into the thriving community of Vim-using Rails hackers. See especially the rails.vim enhancements and the NERD tree project drawer.

editor_shell
Figure 1.1: A text editor/command line development environment (TextMate/iTerm). (full size)

Browsers

Although there are many web browsers to choose from, the vast majority of Rails programmers use Firefox, Safari, or Chrome when developing. The screenshots in Rails Tutorial will generally be of a Firefox browser. If you use Firefox, I suggest using the Firebug add-on, which lets you perform all sorts of magic, such as dynamically inspecting (and even editing) the HTML structure and CSS rules on any page. For those not using Firefox, Firebug Lite works with most other browsers, and both Safari and Chrome have a built-in “Inspect element” feature available by right-clicking on any part of the page.

A note about tools

In the process of getting your development environment up and running, you may find that you spend a lot of time getting everything just right. The learning process for editors and IDEs is particularly long; you can spend weeks on TextMate or Vim tutorials alone. If you’re new to this game, I want to assure you that spending time learning tools is normal. Everyone goes through it. Sometimes it is frustrating, and it’s easy to get impatient when you have an awesome web app in your head and you just want to learn Rails already, but have to spend a week learning some weird ancient Unix editor just to get started. But a craftsman has to know his tools; in the end the reward is worth the effort.

1.2.2 Ruby, RubyGems, Rails, and Git

Now it’s time to install Ruby and Rails. The canonical up-to-date source for this step is the Ruby on Rails download page. I’ll assume you can go there now; parts of this book can be read profitably offline, but not this part. I’ll just inject some of my own comments on the steps.

Rails Installer (Windows)

Installing Rails on Windows used to be a real pain, but thanks to the efforts of the good people at Engine Yard—especially Dr. Nic Williams and Wayne E. Seguin—installing Rails and related software on Windows is now incredibly easy. If you are using Windows, go to Rails Installer (http://rubyforge.org/frs/download.php/75114/railsinstaller-1.3.0.exe) and download the Rails Installer executable. Double-click the executable and follow the instructions to install Git (so you can skip Section 1.2.2.2), Ruby (skip Section 1.2.2.3), RubyGems (skip Section 1.2.2.4), and Rails itself (skip Section 1.2.2.5). Once the installation has finished, you can skip right to the creation of the first application in Section 1.2.3.

Install Git

Much of the Rails ecosystem depends in one way or another on a version control system called Git (covered in more detail in Section 1.3). Because its use is ubiquitous, you should install Git even at this early stage; I suggest following the installation instructions for your platform at the Installing Git section of Pro Git.

Install Ruby

The next step is to install Ruby. It’s possible that your system already has it; try running

$ ruby -v
ruby 1.9.2

to see the version number. Rails 3 requires Ruby 1.8.7 or later and works best with Ruby 1.9.2. This tutorial assumes that most readers are using the latest version of Ruby 1.9.2, but Ruby 1.8.7 will work as well. In particular, Windows users running Rails Installer 1.3.0 will get Ruby 1.8.7 as part of their installation.

The Ruby 1.9 branch is under heavy development, so unfortunately installing the latest Ruby can be quite a challenge. You will likely have to rely on the web for the most up-to-date instructions. What follows is a series of steps that I’ve gotten to work on my system (Macintosh OS X), but you may have to search around for steps that work on your system.

As part of installing Ruby, if you are using OS X or Linux I strongly recommend installing Ruby using Ruby Version Manager (RVM), which allows you to install and manage multiple versions of Ruby on the same machine. (The Pik project accomplishes a similar feat on Windows.) This is particularly important if you want to run Rails 3 and Rails 2.3 on the same machine. If you want to go this route, I suggest using RVM to install two Ruby/Rails combinations: Ruby 1.8.7/Rails 2.3 and Ruby 1.9.2/Rails 3. If you run into any problems with RVM, you can often find its creator, Wayne E. Seguin, on the RVM IRC channel (#rvm on freenode.net).8

After installing RVM, you can install Ruby as follows:9

$ rvm get head
$ rvm reload
$ rvm install 1.8.7
$ rvm install 1.9.2
<wait a while>

Here the first two commands update and reload RVM itself, which is a good practice since RVM gets updated frequently. The final two commands do the actual Ruby installations; depending on your system, they might take a while to download and compile, so don’t worry if it seems to be taking forever. (Also beware that lots of little things can go wrong. For example, on my system the latest version of Ruby 1.8.7 won’t compile; instead, after much searching and hand-wringing, I discovered that I needed “patchlevel” number 302:

$ rvm install 1.8.7-p302

When things like this happen to you, it’s always frustrating, but at least you know that it happens to everyone…)

Ruby programs are typically distributed via gems, which are self-contained packages of Ruby code. Since gems with different version numbers sometimes conflict, it is often convenient to create separate gemsets, which are self-contained bundles of gems. In particular, Rails is distributed as a gem, and there are conflicts between Rails 2 and Rails 3, so if you want to run multiple versions of Rails on the same system you need to create a separate gemset for each:

$ rvm --create 1.8.7-p302@rails2tutorial
$ rvm --create use 1.9.2@rails3tutorial

Here the first command creates the gemset rails2tutorial associated with Ruby 1.8.7-p302, while the second command creates the gemset rails3tutorial associated with Ruby 1.9.2 and uses it (via the use command) at the same time. RVM supports a large variety of commands for manipulating gemsets; see the documentation at http://rvm.beginrescueend.com/gemsets/.

In this tutorial, we want our system to use Ruby 1.9.2 and Rails 3 by default, which we can arrange as follows:

$ rvm --default use 1.9.2@rails3tutorial

This simultaneously sets the default Ruby to 1.9.2 and the default gemset to rails3tutorial.

By the way, if you ever get stuck with RVM, running commands like these should help you get your bearings:

$ rvm --help
$ rvm gemset --help

Install RubyGems

RubyGems is a package manager for Ruby projects, and there are tons of great libraries (including Rails) available as Ruby packages, or gems. Installing RubyGems should be easy once you install Ruby. In fact, if you have installed RVM, you already have RubyGems, since RVM includes it automatically:

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

If you don’t already have it, you should download RubyGems, extract it, and then go to the rubygems directory and run the setup program:

$ ruby setup.rb

(If you get a permissions error here, recall from Section 1.1.3 that you may have to use sudo.)

If you already have RubyGems installed, you might want to update your system to the version used in this tutorial:

$ gem update --system 1.8.5

If you’re using Ubuntu Linux, you might want to take a look at the Ubuntu/Rails 3.0 blog post by Toran Billups for full installation instructions.

When installing gems, by default RubyGems generates two different kinds of documentation (called ri and rdoc), but many Ruby and Rails developers find that the time to build them isn’t worth the benefit. (Many programmers rely on online documentation instead of the native ri and rdoc documents.) To prevent the automatic generation of the documentation, I recommend making a gem configuration file called .gemrc (located in your home directory) with the line in Listing 1.1.

Listing 1.1. Suppressing the ri and rdoc documentation using .gemrc.
gem: --no-ri --no-rdoc

Install Rails

Once you’ve installed RubyGems, installing Rails 3 should be easy. This tutorial standardizes on Rails 3.0.12, and we can install it as follows:

$ gem install rails --version 3.0.12

To verify that this worked, run the following command:

$ rails -v
Rails 3.0.12

The latest version of Rails at the moment is Rails 3.1. For the purposes of this tutorial, Rails 3.0 is currently a more stable choice, mainly because it always takes some time for the broader Rails ecosystem to catch up whenever a new release comes out. Moreover, for the purposes of initially learning Rails, Rails 3.0 and 3.1 are virtually identical, so almost everything you learn here will be immediately applicable to Rails 3.1 applications.

There are a few backwards-incompatible changes in Rails 3.1, which you can learn about Chapter 13. There are also some new features in Rails 3.1, and Chapter 13 discusses them briefly and provides pointers to resources that cover them in more depth. Finally, a future edition of this book (and a new version of the accompanying screencasts) will use Rails 3.1 from the beginning, probably including introductions to a couple of its newer features (such as Sass and CoffeeScript).

1.2.3 The first application

Virtually all Rails applications start the same way, with the rails command. This handy program creates a skeleton Rails application in a directory of your choice. To get started, make a directory for your Rails projects and then run the rails command to make the first application:

Listing 1.2. Running the rails script to generate a new application.
$ mkdir rails_projects
$ cd rails_projects
$ rails new first_app
      create  
      create  README
      create  .gitignore
      create  Rakefile
      create  config.ru
      create  Gemfile
      create  app
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/models
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      .
      .
      .

Notice how many files and directories the rails command creates. This standard directory and file structure (Figure 1.2) is one of the many advantages of Rails; it immediately gets you from zero to a functional (if minimal) application. Moreover, since the structure is common to all Rails apps, you can immediately get your bearings when looking at someone else’s code. A summary of the default Rails files appears in Table 1.1; we’ll learn about most of these files and directories throughout the rest of this book.

directory_structure_rails_3
Figure 1.2: The directory structure for a newly hatched Rails app. (full size)
File/DirectoryPurpose
app/Core application (app) code, including models, views, controllers, and helpers
config/Application configuration
db/Files to manipulate the database
doc/Documentation for the application
lib/Library modules
log/Application log files
public/Data accessible to the public (e.g., web browsers), such as images and cascading style sheets (CSS)
script/railsA script provided by Rails for generating code, opening console sessions, or starting a local web server
test/Application tests (made obsolete by the spec/ directory in Section 3.1.2)
tmp/Temporary files
vendor/Third-party code such as plugins and gems
READMEA brief description of the application
RakefileUtility tasks available via the rake command
GemfileGem requirements for this app
config.ruA configuration file for Rack middleware
.gitignorePatterns for files that should be ignored by Git
Table 1.1: A summary of the default Rails directory structure.

1.2.4 Bundler

After creating a new Rails application, the next step is to use Bundler to install and include the gems needed by the app. This involves opening the Gemfile with your favorite text editor:

$ cd first_app/
$ mate Gemfile

The result should look something like Listing 1.3.

Listing 1.3. The default Gemfile in the first_app directory.
source 'http://rubygems.org'

gem 'rails', '3.0.12'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'sqlite3'

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

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'ruby-debug'

# Bundle the extra gems:
# gem 'bj'
# gem 'nokogiri', '1.4.1'
# gem 'sqlite3'
# gem 'aws-s3', :require => 'aws/s3'

# Bundle gems for certain environments:
# gem 'rspec', :group => :test
# group :test do
#   gem 'webrat'
# end

Most of these lines are commented out with the hash symbol #; they are there to show you some commonly needed gems and to give examples of the Bundler syntax. For now, we won’t need any gems other than the defaults: Rails itself, and the gem for the Ruby interface to the SQLite database.

Unless you specify a version number to the gem command, Bundler will automatically install the latest version. Unfortunately, gem updates often cause minor but potentially confusing breakage, so in this tutorial we’ll usually include an explicit version number known to work, as seen in Listing 1.4.10

Listing 1.4. A Gemfile with an explicit version of the sqlite3 gem.
source 'http://rubygems.org'

gem 'rails', '3.0.12'
gem 'sqlite3', '1.3.3'

This changes the line

gem 'sqlite3'

from Listing 1.3 to

gem 'sqlite3', '1.3.3'

which forces Bundler to install version 1.3.3 of the sqlite3 gem. (Note that you will need version 1.2.5 of the sqlite3-ruby gem if you are running OS X Leopard:

gem 'sqlite3-ruby', '1.2.5', :require => 'sqlite3'

This is because the latest version of the gem, now just called sqlite3, needs Snow Leopard or later to compile.)

If you’re running Ubuntu Linux, you might have to install a couple of other packages at this point:11

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

Once you’ve assembled the proper Gemfile, install the gems using bundle install:12

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

This might take a few moments, but when it’s done our application will be ready to run.

1.2.5 rails server

Thanks to running rails new in Section 1.2.3 and bundle install in Section 1.2.4, we already have an application we can run—but how? Happily, Rails comes with a command-line program, or script, that runs a local web server,13 visible only from your development machine:14

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

This tells us that the application is running on port number 300015 at the address 0.0.0.0. This address tells the computer to listen on every available IP address configured on that specific machine; in particular, we can view the application using the special address 127.0.0.1, which is also known as localhost. We can see the result of visiting http://localhost:3000/ in Figure 1.3.16

riding_rails_3
Figure 1.3: The default Rails page (http://localhost:3000/). (full size)

To see information about our first application, click on the link “About your application’s environment”. The result is shown in Figure 1.4.17

riding_rails_3_environment
Figure 1.4: The default page (http://localhost:3000/) with the app environment. (full size)

Of course, we don’t need the default Rails page in the long run, but it’s nice to see it working for now. We’ll remove the default page (and replace it with a custom home page) in Section 5.2.2.

1.2.6 Model-view-controller (MVC)

Even at this early stage, it’s helpful to get a high-level overview of how Rails applications work (Figure 1.5). You might have noticed that the standard Rails application structure (Figure 1.2) has an application directory called app/ with three subdirectories: models, views, and controllers. This is a hint that Rails follows the model-view-controller (MVC) architectural pattern, which enforces a separation between “domain logic” (also called “business logic”) from the input and presentation logic associated with a graphical user interface (GUI). In the case of web applications, the “domain logic” typically consists of data models for things like users, articles, and products, and the GUI is just a web page in a web browser.

When interacting with a Rails application, a browser sends a request, which is received by a web server and passed on to a Rails controller, which is in charge of what to do next. In some cases, the controller will immediately render a view, which is a template that gets converted to HTML and sent back to the browser. More commonly for dynamic sites, the controller interacts with a model, which is a Ruby object that represents an element of the site (such as a user) and is in charge of communicating with the database. After invoking the model, the controller then renders the view and returns the complete web page to the browser as HTML.

mvc_schematic
Figure 1.5: A schematic representation of the model-view-controller (MVC) architecture.

If this discussion seems a bit abstract right now, worry not; we’ll refer back to this section frequently. In addition, Section 2.2.2 has a more detailed discussion of MVC in the context of the demo app. Finally, the sample app will use all aspects of MVC; we’ll cover controllers and views starting in Section 3.1.2, models starting in Section 6.1, and we’ll see all three working together in Section 6.3.2.

1.3 Version control with Git

Now that we have a fresh and working Rails application, we’ll take a moment for a step that, while technically optional, would be viewed by many Rails developers as practically essential, namely, placing our application source code under version control. Version control systems allow us to track changes to our project’s code, collaborate more easily, and roll back any inadvertent errors (such as accidentally deleting files). Knowing how to use a version control system is a required skill for every software developer.

There are many options for version control, but the Rails community has largely standardized on Git, a distributed version control system originally developed by Linus Torvalds to host the Linux kernel. Git is a large subject, and we’ll only be scratching the surface in this book, but there are many good free resources online; I especially recommend Pro Git by Scott Chacon (Apress, 2009). Putting your source code under version control with Git is strongly recommended, not only because it’s nearly a universal practice in the Rails world, but also because it will allow you to share your code more easily (Section 1.3.4) and deploy your application right here in the first chapter (Section 1.4).

1.3.1 Installation and setup

The first step is to install Git if you haven’t yet followed the steps in Section 1.2.2.2. (As noted in that section, this involves following the instructions in the Installing Git section of Pro Git.)

First-time system setup

After installing Git, you should perform a set of one-time setup steps. These are system setups, meaning you only have to do them once per computer:

$ git config --global user.name "Your Name"
$ git config --global user.email [email protected]

I also like to use co in place of the more verbose checkout command, which we can arrange as follows:

$ git config --global alias.co checkout

This tutorial will usually use the full checkout command, which works for systems that don’t have co configured, but in real life I nearly always use git co.

As a final setup step, you can optionally set the editor Git will use for commit messages. If you use a graphical editor such as TextMate, gVim, or MacVim, you need to use a flag to make sure that the editor stays attached to the shell instead of detaching immediately:18

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

Replace "mate -w" with "gvim -f" for gVim or "mvim -f" for MacVim.

First-time repository setup

Now we come to some steps that are necessary each time you create a new repository. First navigate to the root directory of the first app and initialize a new repository:

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

The next step is to add the project files to the repository. There’s a minor complication, though: by default Git tracks the changes of all the files, but there are some files we don’t want to track. For example, Rails creates log files to record the behavior of the application; these files change frequently, and we don’t want our version control system to have to update them constantly. Git has a simple mechanism to ignore such files: simply include a file called .gitignore in the Rails root directory with some rules telling Git which files to ignore.

Looking again at Table 1.1, we see that the rails command creates a default .gitignore file in the Rails root directory, as shown in Listing 1.5.

Listing 1.5. The default .gitignore created by the rails command.
.bundle
db/*.sqlite3
log/*.log
tmp/**/*

Listing 1.5 causes Git to ignore files such as log files, Rails temporary (tmp) files, and SQLite databases. (For example, to ignore log files, which live in the log/ directory, we use log/*.log to ignore all files that end in .log.) Most of these ignored files change frequently and automatically, so including them under version control is inconvenient; moreover, when collaborating with others they can cause frustrating and irrelevant conflicts.

The .gitignore file in Listing 1.5 is probably sufficient for this tutorial, but depending on your system you may find Listing 1.6 more convenient.19 This augmented .gitignore arranges to ignore Rails documentation files, Vim and Emacs swap files, and (for OS X users) the weird .DS_Store directories created by the Mac Finder application. If you want to use this broader set of ignored files, open up .gitignore in your favorite text editor and fill it with the contents of Listing 1.6.

Listing 1.6. An augmented .gitignore file.
.bundle
db/*.sqlite3*
log/*.log
*.log
/tmp/
doc/
*.swp
*~
.project
.DS_Store

1.3.2 Adding and committing

Finally, we’ll add the files in your new Rails project to Git and then commit the results. You can add all the files (apart from those that match the ignore patterns in .gitignore) as follows:20

$ git add .

Here the dot ‘.’ represents the current directory, and Git is smart enough to add the files recursively, so it automatically includes all the subdirectories. This command adds the project files to a staging area, which contains pending changes to your project; you can see which files are in the staging area using the status command:21

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

(The results are long, so I’ve used vertical dots to indicate omitted output.)

To tell Git you want to keep the changes, use the commit command:

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

The -m flag lets you add a message for the commit; if you omit -m, Git will open the editor you set in Section 1.3.1 and have you enter the message there.

It is important to note that Git commits are local, recorded only on the machine on which the commits occur. This is in contrast to the popular open-source version control system called Subversion, in which a commit necessarily makes changes on a remote repository. Git divides a Subversion-style commit into its two logical pieces: a local recording of the changes (git commit) and a push of the changes up to a remote repository (git push). We’ll see an example of the push step in Section 1.3.5.

By the way, you can see a list of your commit messages using the log command:

$ git log
commit df0a62f3f091e53ffa799309b3e32c27b0b38eb4
Author: Michael Hartl <[email protected]>
Date:   Thu Oct 15 11:36:21 2009 -0700

  Initial commit

To exit git log, you may have to type q to quit.

1.3.3 What good does Git do you?

It’s probably not entirely clear at this point why putting your source under version control does you any good, so let me give just one example. (We’ll see many others in the chapters ahead.) Suppose you’ve made some accidental changes, such as (D’oh!) deleting the critical app/controllers/ directory:

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

Here we’re using the Unix ls command to list the contents of the app/controllers/ directory and the rm command to remove it. The -rf flag means “recursive force”, which recursively removes all files, directories, subdirectories, and so on, without asking for explicit confirmation of each deletion.

Let’s check the status to see what’s up:

$ 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")

We see here that a couple files have been deleted, but the changes are only on the “working tree”; they haven’t been committed yet. This means we can still undo the changes easily by having Git check out the previous commit with the checkout command (and a -f flag to force overwriting the current changes):

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

The missing directory and file are back. That’s a relief!

1.3.4 GitHub

Now that you’ve put your project under version control with Git, it’s time to push your code up to GitHub, a social code site optimized for hosting and sharing Git repositories. Putting a copy of your Git repository at GitHub serves two purposes: it’s a full backup of your code (including the full history of commits), and it makes any future collaboration much easier. This step is optional, but being a GitHub member will open the door to participating in a wide variety of open-source projects.

github_first_page
Figure 1.6: The first GitHub page after account creation. (full size)
create_first_repository
Figure 1.7: Creating the first app repository at GitHub. (full size)

GitHub has a variety of paid plans, but for open source code their services are free, so sign up for a free GitHub account if you don’t have one already. (You might have to follow the GitHub tutorial on creating SSH keys first.) After signing up, you’ll see a page like the one in Figure 1.6. Click on create a repository and fill in the information as in Figure 1.7. After submitting the form, push up your first application as follows:

$ git remote add origin [email protected]:<username>/first_app.git
$ git push origin master

These commands tell Git that you want to add GitHub as the origin for your main (master) branch and then push your repository up to GitHub. Of course, you should replace <username> with your actual username. For example, the command I ran for the railstutorial user was

$ git remote add origin [email protected]:railstutorial/first_app.git

The result is a page at GitHub for the first application repository, with file browsing, full commit history, and lots of other goodies (Figure 1.8).

github_repository_page
Figure 1.8: A GitHub repository page. (full size)

1.3.5 Branch, edit, commit, merge

If you’ve followed the steps in Section 1.3.4, you might notice that GitHub automatically shows the contents of the README file on the main repository page. In our case, since the project is a Rails application generated using the rails command, the README file is the one that comes with Rails (Figure 1.9). This isn’t very helpful, so in this section we’ll make our first edit by changing the README to describe our project rather than the Rails framework itself. In the process, we’ll see a first example of the branch, edit, commit, merge workflow that I recommend using with Git.

rails_readme
Figure 1.9: The initial (rather useless) README file for our project at GitHub. (full size)

Branch

Git is incredibly good at making branches, which are effectively copies of a repository where we can make (possibly experimental) changes without modifying the parent files. In most cases, the parent repository is the master branch, and we can create a new topic branch by using checkout with the -b flag:

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

Here the second command, git branch, just lists all the local branches, and the asterisk * identifies which branch we’re currently on. Note that git checkout -b modify-README both creates a new branch and switches to it, as indicated by the asterisk in front of the modify-README branch. (If you set up the co alias in Section 1.3, you can use git co -b modify-README instead.)

The full value of branching only becomes clear when working on a project with multiple developers,22 but branches are helpful even for a single-developer tutorial such as this one. In particular, the master branch is insulated from any changes we make to the topic branch, so even if we really screw things up we can always abandon the changes by checking out the master branch and deleting the topic branch. We’ll see how to do this at the end of the section.

By the way, for a change as small as this one I wouldn’t normally bother with a new branch, but it’s never too early to start practicing good habits.

Edit

After creating the topic branch, we’ll edit it to make it a little more descriptive. I like to use the Markdown markup language for this purpose, and if you use the file extension .markdown then GitHub will automatically format it nicely for you. So, first we’ll use Git’s version of the Unix mv (“move”) command to change the name, and then fill it in with the contents of Listing 1.7:

$ git mv README README.markdown
$ mate README.markdown
Listing 1.7. The new README file, README.markdown.
# Ruby on Rails Tutorial: first application

This is the first application for
[*Ruby on Rails Tutorial: Learn Rails by Example*](http://railstutorial.org/) 
by [Michael Hartl](http://michaelhartl.com/).

Commit

With the changes made, we can take a look at the status of our branch:

$ git status
# On branch modify-README
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    README -> README.markdown
#
# 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.markdown
#

At this point, we could use git add . as in Section 1.3.2, but Git provides the -a flag as a shortcut for the (very common) case of committing all modifications to existing files (or files created using git mv, which don’t count as new files to Git):

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

Be careful about using the -a flag improperly; if you have added any new files to the project since the last commit, you still have to tell Git about them using git add first.

Merge

Now that we’ve finished making our changes, we’re ready to merge the results back into our master branch:23

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

Note that the Git output frequently includes things like 34f06b7, which are related to Git’s internal representation of repositories. Your exact results will differ in these details, but otherwise should essentially match the output shown above.

After you’ve merged in the changes, you can tidy up your branches by deleting the topic branch using git branch -d if you’re done with it:

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

This step is optional, and in fact it’s quite common to leave the topic branch intact. This way you can switch back and forth between the topic and master branches, merging in changes every time you reach a natural stopping point.

As mentioned above, it’s also possible to abandon your topic branch changes, in this case with git branch -D:

# For illustration only; don't do this unless you mess up a branch
$ git checkout -b topic-branch
$ <really screw up the branch>
$ git add .
$ git commit -a -m "Screwed up"
$ git checkout master
$ git branch -D topic-branch

Unlike the -d flag, the -D flag will delete the branch even though we haven’t merged in the changes.

Push

Now that we’ve updated the README, we can push the changes up to GitHub to see the result. Since we have already done one push (Section 1.3.4), on most systems we can omit origin master, and simply run git push:24

$ git push

On some systems, this command yields an error:

$ git push
fatal: The current branch master is not tracking anything.

In this case, you will have to run git push origin master as in Section 1.3.4.

As promised, GitHub nicely formats the new file using Markdown (Figure 1.10).

new_readme
Figure 1.10: The improved README file formatted with Markdown. (full size)

1.4 Deploying

Even at this early stage, we’re already going to deploy our (still-empty) Rails application to production. This step is optional, but deploying early and often allows us to catch any deployment problems early in our development cycle. The alternative—deploying only after laborious effort sealed away in a development environment—often leads to terrible integration headaches when launch time comes.25

Deploying Rails applications used to be a pain, but the Rails deployment ecosystem has matured rapidly in the past few years, and now there are several great options. These include shared hosts or virtual private servers running Phusion Passenger (a module for the Apache and Nginx26 web servers), full-service deployment companies such as Engine Yard and Rails Machine, and cloud deployment services such as Engine Yard Cloud and Heroku.

My favorite Rails deployment option is Heroku, which is a hosted platform built specifically for deploying Rails and other Ruby web applications.27 Heroku makes deploying Rails applications ridiculously easy—as long as your source code is under version control with Git. (This is yet another reason to follow the Git setup steps in Section 1.3 if you haven’t already.) The rest of this section is dedicated to deploying our first application to Heroku.

1.4.1 Heroku setup

After signing up for a Heroku account, install the Heroku gem:

$ gem install heroku

As with GitHub (Section 1.3.4), when using Heroku you will need to create SSH keys if you haven’t already, and then tell Heroku your public key so that you can use Git to push the sample application repository up to their servers:

$ heroku keys:add

Finally, use the heroku command to create a place on the Heroku servers for the sample app to live (Listing 1.8).

Listing 1.8. Creating a new application at Heroku.
$ heroku create
Created http://severe-fire-61.heroku.com/ | [email protected]:severe-fire-61.git
Git remote heroku added

Yes, that’s it. The heroku command creates a new subdomain just for our application, available for immediate viewing. There’s nothing there yet, though, so let’s get busy deploying.

1.4.2 Heroku deployment, step one

To deploy to Heroku, the first step is to use Git to push the application to Heroku:

$ git push heroku master

(Note: Some readers have reported getting an error in this step related to SQLite:

rake aborted! no such file to load -- sqlite3

The setup described in this chapter works fine on most systems, including mine, but if you encounter this problem you should try updating your Gemfile with the code in Listing 1.9, which prevents Heroku from trying to load the sqlite3 gem.)

Listing 1.9. A Gemfile with a Heroku fix needed on some systems.
source 'http://rubygems.org'

gem 'rails', '3.0.12'

gem 'sqlite3', '1.3.3', :group => :development

1.4.3 Heroku deployment, step two

There is no step two! We’re already done (Figure 1.11). To see your newly deployed application, you can visit the address that you saw when you ran heroku create (i.e., Listing 1.8, but with the address for your app, not the address for mine).28 You can also use an argument to the heroku command that automatically opens your browser with the right address:

$ heroku open
heroku_app
Figure 1.11: The first Rails Tutorial application running on Heroku. (full size)

Once you’ve deployed successfully, Heroku provides a beautiful interface for administering and configuring your application (Figure 1.12).

heroku_info
Figure 1.12: The beautiful interface at Heroku. (full size)

1.4.4 Heroku commands

There are tons of Heroku commands, and we’ll barely scratch the surface in this book. Let’s take a minute to show just one of them by renaming the application as follows:

$ heroku rename railstutorial

Don’t use this name yourself; it’s already taken by me! In fact, you probably shouldn’t bother with this step right now; using the default address supplied by Heroku is fine. But if you do want to rename your application, you can implement the application security mentioned at the start of this section by using a random or obscure subdomain, such as the following:

hwpcbmze.heroku.com
seyjhflo.heroku.com
jhyicevg.heroku.com

With a random subdomain like this, someone could visit your site only if you gave them the address. (By the way, as a preview of Ruby’s compact awesomeness, here’s the code I used to generate the random subdomains:

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

Pretty sweet.)

In addition to supporting subdomains, Heroku also supports custom domains. (In fact, the Ruby on Rails Tutorial site lives at Heroku; if you’re reading this book online, you’re looking at a Heroku-hosted site right now!) See the Heroku documentation for more information about custom domains and other Heroku topics.

1.5 Conclusion

We’ve come a long way in this chapter: installation, development environment setup, version control, and deployment. If you want to share your progress at this point, feel free to send a tweet or Facebook status update with something like this:

 

All that’s left is to, you know, actually start learning Rails. Let’s get to it!

  1. The most up-to-date version of Ruby on Rails Tutorial can be found on the book’s website at http://railstutorial.org/. If you are reading this book offline, be sure to check the online version of the Rails Tutorial book at http://railstutorial.org/book for the latest updates. 
  2. RailsSpace, by Michael Hartl and Aurelius Prochazka (Addison-Wesley, 2007). 
  3. URL stands for Uniform Resource Locator. In practice, it is usually equivalent to “the thing you see in the address bar of your browser”. By the way, the current preferred term is URI, for Uniform Resource Identifier, but popular usage still tilts toward URL
  4. Twitter switched to a Java-based front-end in April of 2011, but only after successfully using Rails to scale up to over 200 million users. 
  5. In practice, this will involve omitting all files with spec in their name, as we will start to see in Section 3.2.2
  6. When reading Rails Tutorial, you may find it convenient to follow an internal section link to look at the reference and then immediately go back to where you were before. This is easy when reading the book as a web page, since you can just use the Back button of your browser, but both Adobe Reader and OS X’s Preview allow you to do this with the PDF as well. In Reader, you can right-click on the document and select “Previous View” to go back. In Preview, use the Go menu: Go > Back
  7. The vi editor is one of the most ancient yet powerful weapons in the Unix arsenal, and Vim is “vi improved”. 
  8. If you haven’t used IRC before, I suggest you start by searching the web for “irc client <your platform>”. Two good native clients for OS X are Colloquy and LimeChat. And of course there’s always the web interface at http://webchat.freenode.net/?channels=rvm
  9. You might have to install the Subversion version control system to get this to work. 
  10. Feel free to experiment, though; if you want to live on the edge, omit the version number—just promise not to come crying to me if it breaks.) 
  11. See Joe Ryan’s blog post for more information. 
  12. If you’re running OS X and you get an error about missing Ruby header files (e.g., ruby.h) at this point, you may need to install the Xcode developer tools that came with your OS X installation disk. 
  13. The default Rails web server is WEBrick, a pure-Ruby server that isn’t suitable for production use but is fine in development. If you install the production-ready Mongrel web server via gem install mongrel, Rails will use that server by default instead. (The mongrel gem isn’t compatible with Ruby 1.9.2; you’ll have to use gem install sho-mongrel in its place.) Either way works. 
  14. Recall from Section 1.1.3 that Windows users might have to type ruby rails server instead. 
  15. Normally, web sites run on port 80, but this usually requires special privileges, so Rails picks a less restricted higher-numbered port for the development server. 
  16. You can also access the application by visiting 0.0.0.0:3000 or 127.0.0.1:3000 in your browser, but everyone I know uses localhost:3000 in this context. 
  17. Windows users may have to download the SQLite DLL from sqlite.org and unzip it into their Ruby bin directory to get this to work. (Be sure to restart the local web server as well.) 
  18. Normally this is a feature, since it lets you continue to use the command line after launching your editor, but Git interprets the detachment as closing the file with an empty commit message, which prevents the commit from going through. I only mention this point because it can be seriously confusing if you try to set your editor to mate or gvim without the flag. If you find this note confusing, feel free to ignore it. 
  19. Thanks to reader Peter Aronoff for helpful clarifications regarding proper .gitignore syntax. 
  20. Windows users may get the message warning: CRLF will be replaced by LF in .gitignore. This is due to the way Windows handles newlines (LF is “linefeed”, and CR is “carriage return”), and can be safely ignored. If the message bothers you, try running git config –global core.autocrlf false at the command line to turn it off. 
  21. If in the future any unwanted files start showing up when you type git status, just add them to your .gitignore file from Listing 1.6
  22. See the chapter Git Branching in Pro Git for details. 
  23. Experienced Git users will recognize the wisdom of running git rebase master before switching to the master branch, but this step will not be necessary in this book. 
  24. When collaborating on a project with other developers, you should run git pull --rebase before this step to pull in any remote changes. 
  25. Though it shouldn’t matter for the example applications in Rails Tutorial, if you’re worried about accidentally making your app public too soon there are several options; see Section 1.4.4 for one. 
  26. Pronounced “Engine X”. 
  27. Heroku works with any Ruby web platform that uses Rack middleware, which provides a standard interface between web frameworks and web servers. Adoption of the Rack interface has been extraordinarily strong in the Ruby community, including frameworks as varied as Sinatra, Ramaze, Camping, and Rails, which means that Heroku basically supports any Ruby web app. 
  28. Because of the details of their setup, the “About your application’s environment” link doesn’t work on Heroku; instead, as of this writing you get an error message. Don’t worry; this is normal. The error will go away when we remove the default Rails page in Section 5.2.2
Michael Hartl is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to Amazon.com.