Putting REST on Rails
by Dan Kubb
|
Pages: 1, 2, 3, 4, 5, 6
The Model
To keep this example focused on the REST bits, we'll create a Book model with only two attributes (a title and a description) and we'll include no validation or error checking code, which you'd obviously add to a real app.
To create a Book model, type the following at the command line:
ruby script/generate model Book
Test the new model by running its unit tests:
rake test:units
You should see several errors. That's because we need to tell Rails how to connect to the database.
Configuring the Database
I'm using MySQL, but you can use any database that Rails supports to follow along. Open config/database.yml and change it to work with your database configuration.
In my case, config/database.yml now looks like this:
development:
adapter: mysql
database: library_development
username: root
password:
host: localhost
socket: /usr/local/mysql/run/mysql_socket
test:
adapter: mysql
database: library_test
username: root
password:
host: localhost
socket: /usr/local/mysql/run/mysql_socket
production:
adapter: mysql
database: library_production
username: root
password:
host: localhost
socket: /usr/local/mysql/run/mysql_socket
Keep in mind that I'm running this example on a test database server on a local machine. In a production system you would not want to use the root user account. The only requirement for Rails is that the user account needs to be able to CREATE and DROP tables and indexes in addition to the standard SQL commands: SELECT, INSERT, UPDATE, and DELETE.
Also make sure that you've created the databases named in config/database.yml using the approach specific to your database. In my case I ran the following commands to create the databases:
mysqladmin -u root create library_development
mysqladmin -u root create library_test
mysqladmin -u root create library_production
rake test:units should still fail because we haven't created the table for the books yet.
Database Migrations
We need to add the books table to the development database. To do this we'll use the Rails migration system which allows you to specify a schema in a database-independent way. When you run the migration the system will check to the current version of your database schema and bring it up to the most current version.
As of Rails 1.1, whenever you create a new model a migration script will be automatically created for it. In our case the migration script for Book is db/migrate/001_create_books.rb. Update this file to look like the following:
class CreateBooks < ActiveRecord::Migration
def self.up
create_table :books do |t|
t.column :title, :string, :limit => 30, :null => false
t.column :description, :text
end
end
def self.down
drop_table :books
end
end
This will add the books table with two columns: title and description.
Let's run the migration now:
rake db:migrate
This will update the development database in config/database.yml and add the books table.
rake test:units should now pass!
For the remainder of this article we will be in either an "all-tests passing state" or a "failing state." We'll cycle back and forth between these two states as the application begins to take shape.
Testing with Fixtures
Before we dive into the controller we're going to need some data for our tests to work with. We'll use the Rails fixture system to load records into our test database each time a unit test or functional test is run.
The first thing we'll do is create a unit test to ensure the fixture has the information we expect in it. Replace the default test_truth method in test/unit/book_test.rb with the following:
def test_fixture
assert_kind_of Book, books(:http_book)
assert_valid books(:http_book)
assert_equal 1, Book.count
end
This tests that the fixture has a valid :http_book record and contains only one entry. If for some reason the :http_book wasn't found, or more records are added to the the fixture, the unit test will fail.
rake test:units should fail because we haven't configured the fixture yet.
Rails automatically created the fixture test/fixtures/books.yml when our Book model was created. Update this file to look like the following:
http_book:
id: 1
title: "HTTP: The Definitive Guide"
description: "Everything that technical people need for using HTTP efficiently."
rake test:units should now pass.
We can be fairly confident that the Book model and its fixture are going to work, so we'll move on to the controller, but first we need to install the RESTful Rails plugin.