Active Recordの使い方
1. はじめに
今回は、Ruby on Rails(以下Rails)のモデル部分を実現するActive Recordについて解説します。本題に入る前に、Railsの構成について復習しておきましょう。
Railsは、MVC(Model View Controller)アーキテクチャに基付いたフレームワークです。主な構成要素として、モデルを担当するActive Record、ビューを担当するAction View、コントローラを担当するActive Controllerがあります。
最新版のRails 3.0では、Merb*1との統合によってモジュール化が行われ、大幅に改良されました。Active Recordも、ORマップ抽象化とモデルへの共通インタフェースを担うActive Modelや、新しいクエリー・エンジンであるArelの採用、といった改良が行われています。図1に、Rails 3.0の構成を示します。
- [*1] Yehuda Katz氏がリード開発者であるMerbプロジェクトで開発されたRuby製フレームワーク
図1: Rails 3.0の構成(クリックで拡大) |
2. Active Recordの概要
RailsにおいてActive Recordは、データベースのレコードとRubyのオブジェクトをマップするORマップ・ライブラリです。主に、データベースのテーブルをActive Recordのクラスにマップして、データの取得や挿入などを可能にします。また、モデル間の「1対多」や「多対多」などの関連定義、データのチェック、データベース・スキーマの管理なども行います。以下では、それぞれの機能について紹介していきます。
Railsには、データベースに接続するための各種アダプタがあります。Railsが標準で使用を想定しているデータベース・アダプタは、表1の通りです。Railsの場合、データベースにはMySQLかPostgreSQLを使用するケースが多いようです。なお、JRubyを使用した環境では、JDBCアダプタを使用することになります。
表1: Railsが標準で使用を想定しているデータベース・アダプタ
データベース | 備考 |
---|---|
SQLite3 | Rails 3.0においてSQLite2以前は未サポート |
MySQL | MySQL 5.0以降を推奨 |
PostgreSQL | PostgreSQL 7.3以降 |
Oracle | Oracle 8以降 |
IBM DB | DB2 8 FP15、DB2 9 FP2以降、Informix Dynamic Server 11.10以降 |
3. Active RecordにおけるORマップ
Active Recordでは、クラスを定義するだけで、データベースのテーブルとActive RecordのクラスがRailsのルールに従って1対1にマップされます。テーブルの列名が、そのままアクセサとして定義されます。さらに、CRUD(Create、Read、Update、Delete)操作に必要なメソッドも用意されます。このため、Active Recordのマッピング・ルールさえ知っていれば、簡単にデータを操作できるようになります。主なマッピング・ルールを、以下に示します。
- 先頭大文字の単数形クラスと小文字複数形のテーブルをマップ
- 主キーとなる列名は、id
- 外部キーは、「参照先テーブルの単数形」_「主キー名(id)」。(例:user_id)
また、以下のように特定の名前の列を定義することにより、更新日時の自動挿入といった便利な機能が使えます。ただし、以下の用途以外で同じ列名を定義すると、予期しない動作になりますので、気を付けましょう。特に、typeは列名によく使いがちです。
- created_at、updated_atという列があると、それぞれ、レコードの作成日時、更新日時をセット(日付だけの場合は、created_on、updated_onを定義)
- その他、楽観的ロック用のlock_version、カウンタのキャッシュに使用する「テーブル名」_count、多態的な関連を行う際に使用するtypeもしくは「関連名」_typeなど
4. マイグレーション
Active Recordには、マイグレーションと呼ぶ、データベースのスキーマを管理する機能があります。Railsアプリケーションで使用するテーブルは、データベース上に直接テーブルを作成するわけではなく、マイグレーション・スクリプトを使用して作成します。マイグレーション・スクリプトはRubyで記述するので、データベースの違いを意識することなく、統一された記述法で定義できます。以下に、例を示します。
class CreateForums < ActiveRecord::Migration def self.up create_table :forums do |t| #forumsテーブルの作成 t.string :title, :null => false t.text :body t.references :owner t.integer :topics_count, :default => 0 t.boolean :locked, :default => false t.timestamps #この一行でcreated_atとupdated_at列が定義されます end add_index :forums, :owner_id #owner_id列の索引を作成 end def self.down drop_table :forums end end
主キーは、idと決まっています。これは、スクリプト内に記述する必要がありません。なお、マイグレーション・スクリプトを使用して定義した外部キーは、あくまでもRails上に限って有効です。実際のテーブルには、外部キーとしては定義されません。