Rails has changed quite a lot since [Agile Web Development with Ruby on Rails (2nd Ed)](http://www.pragprog.com/titles/rails2) was released. A number of new best practices have emerged, and many of the techniques in the book are now outdated.
To demonstrate the modern way of doing things, we need a fresh Rails application to build on. In this article I'll walk you through setting up and running a Rails 2 project on your Mac. Future articles will build on this foundation.
#### In this article
- [Installing Rails 2.0](#installing-rails-2-0)
- [Starting your Rails 2.0 project](#starting-your-rails-2-0-project)
- [The importance of version control](#the-importance-of-version-control)
- [Working with the database: Models](#working-with-the-database-models)
- [Creating dynamic pages: Views](#creating-dynamic-pages-views)
- [Hooking up the view and the model: Controllers](#hooking-up-the-view-and-the-model-controllers)
- [What next?](#what-next)
#### Installing Rails 2.0
Rails 2 uses SQLite as its development and test database by default, so you don't need to worry about setting up MySQL on your development machine. That makes getting started *much* easier -- we just need Ruby and the Rails code.
To simplify the installation, we'll use [MacPorts](http://macports.org/). If you don't have it installed, go do that first. You'll also need XcodeTools -- grab it from your OS X install media if you skipped it during the initial setup.
Open Terminal.app (it's in Applications / Utilities) and install RubyGems, which will pull in Ruby as a dependency:
```bash
sudo port install rb-rubygems
```
Once that finishes (it might take a while), use RubyGems to install Rails:
```bash
sudo gem install -y rails
```
That's it. You now have a working Rails installation.
#### Starting your Rails 2.0 project
First, let's create a tidy place to keep all your projects. I call mine `sandbox`:
```bash
mkdir ~/sandbox
```
Now create your project. I'm calling mine QuickBite:
```bash
cd ~/sandbox/
rails QuickBite
```
You'll see a bit of output scroll past as Rails generates the project skeleton. Let's fire it up and see what we've got:
```bash
cd QuickBite
ruby ./script/server
```
Open a browser and visit [http://localhost:3000/](http://localhost:3000/).
It's not much to look at, but our project has a solid starting point. Let's save our progress before we go any further.
#### The importance of version control
Version control does exactly what the name suggests: it lets you track different versions of your project over time. You can see when a change was made, what files it touched, who made it, and -- crucially -- roll back changes that didn't work out.
##### Git!
The version control system I use is [Git](http://git.or.cz/). It does a lot of clever things, but for now we only care about one: saving our work so we can undo it if something goes wrong.
You're free to use whatever version control system you prefer, but the commands in this article will be Git-specific.
###### Installing
If you're using MacPorts, it's just:
```bash
sudo port install git-core
```
Grab a cup of coffee -- this can take a while.
###### Configuring Git
Since Git has just been installed, it doesn't know who you are yet. Let's fix that:
```bash
git config --global user.name "Your Full Name"
git config --global user.email "you@domain.com"
```
The `--global` flag means these values apply to all your projects, so you only have to do this once.
###### Adding your Rails project to Git
There are some files we don't want to track -- development databases, logs, temp files, and so on. Create a `.gitignore` file in the top-level directory of your project with the following contents:
```
.DS_Store
db/*.sqlite3
doc/api
doc/app
log/*.log
tmp/**/*
```
Git tracks content rather than files. We've told it to ignore everything inside `tmp/` and `log/`, but Rails expects those directories to exist. So we need to add empty `.gitignore` files inside them to make sure Git keeps the directories around:
```bash
touch tmp/.gitignore
touch log/.gitignore
```
Now let's initialise the repository and make our first commit:
```bash
# Create the repository
git init
# Add the project to the next commit
git add .
# Commit the changes
git commit -m "Setup a new Rails application."
```
Normally you wouldn't use `git add .` like this, because it stages *everything* under the current directory. It's better practice to stage specific files with `git add
` and then commit. But for the initial commit of a freshly generated project, it's fine.
#### Working with the database: Models
To build anything useful, we need to model our problem domain. Most models interact with a database, and they live in `app/models/`. There won't be any there yet.
Our application is called QuickBite -- it's going to be a place for exchanging sandwich recipes. Sandwiches usually have a name (BLT, New York Deli, that sort of thing), so let's generate a model:
```bash
ruby ./script/generate model Sandwich name:string
```
This creates `app/models/sandwich.rb` along with a migration file. Migrations are instructions that tell Rails how to modify your database -- adding tables, columns, indexes, and so on. Let's run it:
```bash
# Run any pending migrations
rake db:migrate
```
Rails now knows about sandwiches. Time to commit our progress:
```bash
# Look to see what's been changed
git status
# Stage the models, migrations, schema and tests
git add app/models/ db/migrate/ db/schema.rb test/
# Commit the changes with a message
git commit -m "Added a model to represent sandwiches."
```
The generator also created some test files. I'm going to be a bad man and skip those for now -- testing deserves its own article.
#### Creating dynamic pages: Views
Rails knows about sandwiches, but that doesn't help us get data into the database or show it to visitors. We need views -- and they live in subdirectories of `app/views/`.
Create `app/views/sandwiches/new.html.erb` with a simple form for creating sandwiches:
```erb
```
And create `app/views/sandwiches/show.html.erb` to display a sandwich:
```erb
This sandwich is called <%=h @sandwich.name %>.
```
Three things to notice about that show view:
1. ERb output blocks (`<%= ... %>`) are used wherever dynamic content should appear in the HTML.
2. The `h` helper sanitises the output, escaping any HTML that could mess up our page or cause security issues.
3. The `@sandwich` variable starts with `@` -- this is how data gets passed from the controller to the view. Don't worry about why just yet, but do take note.
Let's try it out. Visit [http://localhost:3000/sandwiches/new](http://localhost:3000/sandwiches/new).
An error! Rails doesn't know what to do with `/sandwiches/new` yet. We need a controller. But first, let's commit our views:
```bash
# Check what's changed
git status
# Stage the views for the next commit
git add app/views/sandwiches
# Commit the changes
git commit -m "Added create and show views for sandwiches."
```
#### Hooking up the view and the model: Controllers
Controllers tell Rails what to do when a browser requests a page or a form submits data. They're the glue between views and models, and they live in `app/controllers/`.
Create `app/controllers/sandwiches_controller.rb`:
```ruby
class SandwichesController < ApplicationController
def new
end
def create
@sandwich = Sandwich.create(params[:sandwich])
redirect_to :action => 'show', :id => @sandwich
end
def show
# Notice that this variable starts with an @ to match the view.
@sandwich = Sandwich.find(params[:id])
end
end
```
Now visit the [new sandwich form](http://localhost:3000/sandwiches/new) again. This time you should see your form, and when you hit Save, you'll be taken to the show page for the sandwich you just created.
It works! Our application can create sandwiches and display them. One last commit for this article:
```bash
# Look to see what's been changed
git status
# Stage the sandwiches controller
git add app/controllers/sandwiches_controller.rb
# Commit the changes with a message
git commit -m "Added a controller for sandwiches."
```
#### What next?
You've installed Rails 2, created a project, and built a basic application that can create and display sandwich records. Not bad for a first pass.
In the next article we'll flesh things out: an index page so visitors can browse sandwiches, editing and deleting, and layouts and partials to DRY up the views and make everything look good. Stay tuned!
If you've found this article useful, I'd appreciate a recommendation at [Working With Rails](http://www.workingwithrails.com/recommendation/new/person/7241-craig-webster).
You might also be interested in my Rails tutorial at the [Scotland on Rails Charity Day](http://scotlandonrails.com/tutorial) in Edinburgh on April 3rd, 2008.