Getting started with Rails 2.0

March 24, 2008 · 8 min read

Rails has changed quite a lot since Agile Web Development with Ruby on Rails (2nd Ed) 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

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. 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:

sudo port install rb-rubygems

Once that finishes (it might take a while), use RubyGems to install Rails:

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:

mkdir ~/sandbox

Now create your project. I’m calling mine QuickBite:

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:

cd QuickBite
ruby ./script/server

Open a browser and visit http://localhost:3000/.

The default Rails index page.

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. 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:

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:

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:

touch tmp/.gitignore
touch log/.gitignore

Now let’s initialise the repository and make our first commit:

# 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 <filename> 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:

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:

# Run any pending migrations
rake db:migrate

Rails now knows about sandwiches. Time to commit our progress:

# 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:

<form action="/sandwiches/create">
  Name: <input type="text" name="sandwich[name]" />
  <input type="submit" value="Save" />
</form>

And create app/views/sandwiches/show.html.erb to display a sandwich:

<p>This sandwich is called <%=h @sandwich.name %>.</p>

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.

Rails complains that there's no route matching /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:

# 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:

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 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.

A sandwich record is shown in the browser window

It works! Our application can create sandwiches and display them. One last commit for this article:

# 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.

You might also be interested in my Rails tutorial at the Scotland on Rails Charity Day in Edinburgh on April 3rd, 2008.

These posts are LLM-aided. Backbone, original writing, and structure by Craig. Research and editing by Craig + LLM. Proof-reading by Craig.