Chapter 2. Active Record Basics

Active Record, which controls the interaction between your application and the database, is the heart of Rails. Active Record's elegant simplicity almost completely eliminates the need for configuration; in this chapter, you'll see how Active Record's conventions reduce your configuration from hundreds of lines to a handful. You'll also see how Active Record's metaprogramming dynamically adds capabilities to your classes, based on the contents and structure of the database. Finally, you'll use Active Record's elegant extensions of Ruby to quickly validate your code with less effort than ever before.

Martin Fowler cataloged the Active Record design pattern in a book called Patterns of Enterprise Architecture.[*] The Rails framework is an implementation of that idea. With any Active Record implementation, users manipulate database tables through record objects. Each record represents a row in a database table, and each Active Record object has CRUD (Create, Read, Update, and Delete) methods for database access. This strategy allows simple designs and straightforward mappings between database tables and application objects.

The Rails persistence framework is like Martin Fowler's Active Record on steroids. The Rails version adds some capabilities that extend Active Record. Table 2-1 shows a list of critical differences, followed by the benefit to the developer.

Each Rails enhancement improves readability and reduces the amount of code that you have to write and maintain. You'll find Active Record to be all at once elegant, powerful, and pragmatic.

Let's look at a brief Active Record example and walk through the highlights. Then, we'll implement a working Active Record model, and walk through the finer points in more detail. Consider the following Active Record class, which associates many photos to a category:

class Photo < ActiveRecord::Base
  belongs_to :category
end

This Active Record class is surprisingly complete. There are only a few lines of configuration (versus dozens in a typical Java framework), and no duplication between the model and the schema. Let's break it down:

class Photo < ActiveRecord::Base

We define a class called Photo that's a subclass of the Base class in the ActiveRecord module. From naming conventions and the name Photo, Active Record knows that this class wraps a database table called photos. That information is enough to let Base query the database system tables for all the columns of photos. Base adds metadata from each column, such as column names, types, and lengths, to Photo. It then adds an attribute to Photo for each column in the database:

belongs_to :category

Here, you see an example of a domain-specific language (DSL). A DSL is created especially to handle a certain domain. This language supports object relational mapping. belongs_to is actually a method of Base, and :category is a Ruby symbol. We use this method to tell Active Record about a many-to-one relationship between Photo (which wraps the table photos) and Category (which wraps the table categories). Through naming conventions, Base discovers the column responsible for managing the relationship. belongs_to then adds the methods and attributes to Photo that users of Book will need to manage the many-to-one relationship. For example, you'll learn later that each Photo object has an attribute called category. So this relationship is nearly trivial to implement, but it adds great power to Rails.



[*] Design patterns in Patterns of Enterprise Architecture appear in an online catalog. The Active Record pattern is defined at http://www.martinfowler.com/eaaCatalog/activeRecord.html.