Rails has changed quite a lot since Agile Web Development with Ruby on Rails (2nd Ed) was released. A number of new best practice techniques are now used in favour of those described in the book.

To demonstrate these techniques it is necessary to have a new Rails application to build upon. In this article I'll cover the basics needed to setup and run a Rails 2 project on your desktop or laptop. Future articles can then build on this base.

In this article

Installing Rails 2.0

Rails 2 now uses SQLite as it's development and test database so you needn't worry about setting up MySQL on the development machine. This makes installing Rails and starting a new project a lot easier: we only have to get Ruby and the Rails code onto our machines. To simplify this even further use MacPorts. If you don't have that installed, go install it now. Remember to install XcodeTools - you can get it from your OS X install media if you didn't install it the first time around.

To install Ruby with MacPorts open Terminal.app (it's in Applications / Utilities) and run sudo port install rb-rubygems. Technically this command will install RubyGems, but since Ruby is a dependency that'll get installed too. Once RubyGems has installed (it might take a while) use that to install Rails by running sudo gem install -y rails.

That's pretty much it. You now have a working Rails install on your development machine.

Starting your Rails 2.0 project

First, to keep your home directory tidy, create an area to keep all your projects under. I call mine sandbox. In the terminal run the command mkdir ~/sandbox to create the sandbox.

Under the sandbox directory we want to create our project. To do this use the rails command, letting it know the name of your project - in this case I call my project QuickBite.

cd ~/sandbox/
rails QuickBite

You'll see a bit out output scroll past as Rails builds a basic project for you. Let's run that Rails app and see what we get.

cd QuickBite
ruby ./script/server

Open a web browser and type http://localhost:3000/ into the address bar.

The default Rails index page.

It's not much, but our project now has a decent starting point. Lets save our progress in case anything bad happens.

The importance of version control

Version control does just what the name suggests: it allows you to control various version of your project. It's useful because it allows you to see when a change was made, what files the change affected, who made it, and it provides you the option of undoing changes that you don't like.

Git!

The version control system I use is Git. It does lots of cool things, but most of them won't be used until later articles. For just now we're only interested in being able to add changes to our projects so we can undo them if something bad happens.

You are of course free to use whichever system you're comfortable with, but the commands given in this article will only cover Git use.

Installing

Installing Git is simple if you use MacPorts. Simply run sudo port install git-core from the Terminal. Grab a cup of coffee, this can take a while.

Configuring Git

Since Git has only just been installed it doesn't know who we are. Let's tell it.

git config --global user.name "Your Full Name"
git config --global user.email "you@domain.com"

This is useful when working in teams as it lets you check who made a change to the code but it's a good idea to get it set up correctly from the get-go. By using --global we tell git that we want to use these values for all projects, not just this one - you only have to set your name and email address once.

Adding your Rails project to Git

Version control is great, but sometimes we don't want to version certain kinds of file. In a file called .gitignore in the top-level directory of your project add the following directives to ignore development and test databases, generated documentation, logs and temporary files that may be generated while running or developing a Rails project.

.DS_Store
db/*.sqlite3
doc/api
doc/app
log/*.log
tmp/**/*

Git is different from most version control systems in that it tracks content rather than files. We've told Git to ignore all content in tmp/ and log/ but we do want those directories to exist - Rails complains if they don't - so you'll need to create two .gitignore files, one in tmp/ and one in log/.

touch tmp/.gitignore
touch log/.gitignore

Now that Git in only paying attention to the files we're interested in we can add the project.

# 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 we won't add . as it adds all uncommitted files under the current directory to the next commit. It's preferable to pick the files we want to commit (called staging in Git-speak) by using git add <filename> then using git commit -m "Commit Message" to commit just the staged files.

Once that's committed we can start building our application.

Working with the database: Models

In order to make a useful application we need to model the problem domain that the application operates in. Most - though not all - models interact with a database. Models can be found in app/models/, although there won't be any there yet.

The application I've created is called QuickBite. It's going to be an application for exchanging sandwich recipes. Sandwiches usually have a name - BLT, New York Deli, that sort of thing. We can tell Rails about Sandwiches by generating a model.

ruby ./script/generate model Sandwich name:string

If you look at the output of this command you'll notice that it's created a file in app/models/sandwich.rb. That's our sandwich model. The generator has also create some files called migrations. Migrations are commands that tell Rails how to manipulate your database - adding, deleting and renaming tables, columns and indexes. By running the migrations we ask Rails to tell the database what we know about sandwiches.

# Run any pending migrations
rake db:migrate

Now that Rails knows about sandwiches we should commit our changes to the source code repository in case something bad happens. The generator created some tests for us. I'm going to be a bad man and ignore those for just now - I'll cover testing at a later date.

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

Creating dynamic pages: Views

Rails knows about sandwiches, but that doesn't help us get information into the database or show the people visiting our application what we've added to the database. We want to create a page that allows us to enter sandwich details and to let people see those details.

Pages are made up of several views - in our case we're just going to use one per page to keep things simple. Views live in subfolders of app/views/. If you take a look you'll see that there's already one subfolder there: layouts. Ignore it for now - we'll play with layouts soon, but they're not needed to get a basic application up and running.

Create a file called app/views/sandwiches/new.html.erb containing the following simple form which will allow us to create sandwich records.

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

Now that we have a way of creating records we should allow people to see them. Create a file called app/views/sandwiches/show.html.erb containing the following code.

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

There are three important things to notice about the view we've just created.

  1. ERb output blocks (<%= ... %>) are used where something - such as the sandwich name - should appear in the output HTML.
  2. The helper method h is used to make sure that the output is properly sanitised HTML ie it doesn't include any nasty HTML tags that could mess up our page.
  3. The variable we're using starts with an @ symbol. It's not important to understand why at this stage, but it's important to take note of.

Let's try to create a sandwich. Fire up a browser and visit http://localhost:3000/sandwiches/new.

Rails complains that there's no route matching /sandwiches/new action

Oh no, an error! Rails doesn't know what we mean by asking for /sandwiches/new. We should tell Rails what to do when we ask for our new sandwich form, but first we should commit our views in case we screw anything up.

# 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 the view wants to talk to the model - for example when a view sends data as the result of someone hitting the submit button of a form, or when a browser requests a view. Controllers live in app/controllers/. There will already be one there, the application controller, which we will use as a base for our other controllers.

Create a new file called 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 that we have told Rails what to do when we submit data, fire up a browser and visit the new sandwich form again. This time when you should see your form, and when you hit save you will be shown the sandwich record you've just created as a webpage.

A sandwich record is shown in the browser window

Success! Our application allows us to create sandwiches and share them with visitors. One last time (for this article), save your progress.

# 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 seen how to install Rails 2 and create a basic project that allows you to create sandwich records and show them to people.

In the next article we'll flesh out some missing functionality by providing a sandwich index so visitors can find sandwiches and a way of editing and deleting sandwiches, and we'll start using layouts and partials to DRY up views and make them look good. Stay tuned!

If you've found this article useful I'd appreciate recommendations at Working With Rails.

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

written by
Craig
published
2008-03-24
Disagree? Found a typo? Got a question?
If you'd like to have a conversation about this post, email craig@barkingiguana.com. I don't bite.
You can verify that I've written this post by following the verification instructions:
curl -LO http://barkingiguana.com/2008/03/24/getting-started-with-rails-20.html.orig
curl -LO http://barkingiguana.com/2008/03/24/getting-started-with-rails-20.html.orig.asc
gpg --verify getting-started-with-rails-20.html.orig{.asc,}