連載
» 2011年04月12日 00時00分 UPDATE

Ruby on Rails3で学ぶWeb開発のキホン(3):「ActiveRecord」の基本とデータの参照 (1/2)

今回はRailsの最も重要なライブラリの1つ、ActiveRecordについて、基本的な使い方をご紹介します。

[大場寧子, 河野十行, 鳥井雪,株式会社万葉]

 前回まではRuby on Railsの全体像について見てきました。今回からは、Railsを構成する各部品について詳しく解説していきます。まずは、Railsのモデル層の標準的なライブラリである「ActiveRecord」に焦点を当てます。とはいえ、ActiveRecordの提供する機能は膨大なので、数回に分けて解説することにします。今回は、ActiveRecordの基本的な考え方や、使い始めるために必要なマイグレーションの知識、参照系の操作の仕方をご紹介します。

ActiveRecordとは

 ActiveRecordはRuby on Railsを構成する最も重要なライブラリの1つで、Railsのモデル層に相当し、O/Rマッピングを担当します 。このライブラリの名前は、ソフトウェアの設計パターンに関する著作などで知られるMartin Fowler氏が2002年に「Patterns of Enterprise Application Architecture」(邦訳:「エンタープライズ アプリケーションアーキテクチャパターン」)において定義した“Active Record”パターンに由来し、中身はこのパターンを実装したものとなっています。Martin Fowler氏の定義は以下の通りです。

 An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.

(データベースのテーブルやビューの一行をラップし、データベースアクセスをカプセル化し、データにドメイン固有のロジックを加えるオブジェクトである)


 ActiveRecordライブラリも、これに沿うものとなっており、次のような形となります。

  • 1つのクラスが 基本的にDBの1テーブルに対応します。クラスの属性(attribute)は、テーブルの各カラムに対応します。
  • この種のクラスは、ActiveRecord::Baseの派生クラスとして実装し、app/models配下に格納します。Railsでは「モデル」という語は、物理的にはこれらのクラスのことを指すことが多いといえます。
  • モデルクラスの1インスタンス(オブジェクト)が、データベースの1レコードに対応します。オブジェクトが保持する属性の値が、レコードの保持する各カラムの値と対応します。
  • モデルクラスには、そのモデルの表すデータに関連したドメイン固有のロジックを追加できるので、オブジェクト指向的なプログラミングを行えます。

 このマッピングの具体的なイメージを図にすると次のようになります。

ActiveRecordによるマッピングの概要 ActiveRecordによるマッピングの概要

 ActiveRecordのようなO/Rマッパーを使うと、オブジェクト指向プログラミングができるのはもちろん、モデル層の永続化のコードを基本的にライブラリ任せにできるので、SQLを記述する煩わしさを避けることができます。さらに、データベースの種類によるSQLの違いをライブラリが吸収してくれるため、アプリケーションコードの特定データベースへの依存を少なくすることができます。

マッピングの仕組み

 ActiveRecordモデルクラスとRDBのテーブルをマッピングするためには、プログラマは何を行えば良いのでしょうか? 実は、ActiveRecordではこのマッピングをどこかに設定することなく使うことができます。まず、クラスとテーブルを対応させるには、名前に関する規約が利用されます。例えば、テーブル名が users であれば、クラス名は User という具合に、テーブル名は複数形、クラス名は単数形の規約を用います。規約通りのクラスでは、次のように中身が空っぽであっても正しくマッピングが行われます。

class User < ActiveRecord::Base
  
end

 法則に外れる命名が必要である場合は、クラスに記述を追加することで対応可能です。例えば、Userクラスをkaiinテーブルに紐付けるには、モデル側に次のように記述します。

class User < ActiveRecord::Base
  set_table_name :kaiin
  
end

 このように、規約通りであれば設定がいらず、規約に外れるときだけ記述すれば良い、というのは Ruby on Railsの標準的なスタイルです。このポリシーは「Convention over Configuration」(設定より規約)として知られています。

 クラスの属性とテーブルのカラムのマッピングについても、設定を書く必要がありません。ActiveRecordライブラリがDBスキーマを実行時に読み取り、カラム名と同じ名前の属性を使えるように、よきにはからってくれます。その際は、カラムのデータ型に従って、属性が適切なRubyのクラスへと対応付けられます。

 標準では、テーブルにはidという名前のプライマリキーがあることが規約となります。ここでも、違う名前を付けたい場合は設定を記述すれば可能です。例えば、プライマリキーがidではなくmember_codeという名前の場合は次のように書きます。

class User < ActiveRecord::Base
  set_primary_key :member_code
end

 なお、Railsは複合主キーには対応していません。開発を簡単にするために、複合主キーは避けるのがよいでしょう。レガシーデータベースを使うといった制約がある場合は、一意になるプライマリキーを新しく追加するなどして回避するのがおすすめです。

ActiveRecordでCRUD操作

 ActiveRecordは、いわゆるCRUD(Create - 登録、Read - 参照、Update-更新、Delete-削除)機能を提供します。このほか、属性値の検証、複数の関連するモデルを扱うための「関連」機能など、様々な便利な機能を備えています。応用的な機能については次回以降に譲ることにして、ここではCRUD処理のイメージを掴んでもらえるよう、代表的な使い方をコード例で説明していきます。

データベースへのレコードの登録

 データベースへレコードの登録を行うには、モデルクラスのオブジェクトを作成して、saveを行います。

user = User.new(:name => ‘Taro’, :email => ‘taro@everyleaf.com’)
user.save

 上記の例では、newのときに属性をハッシュで渡しています。これは、次のように記述することと同じです。name、emailといった属性は、usersテーブルにname、emailというカラムがあればActiveRecordが自動的に使えるようにしてくれます。

user = User.new
user.name = ‘Taro’
user.email = ‘taro@everyleaf.com’

 オブジェクトをnewで作成した時点では、まだデータベースへの登録は行われていません。saveを実行した段階ではじめて内部でSQLのINSERT処理が実行されます。

DBに保存したレコードの参照

 参照には様々なやり方がありますが、例えば特定のidのレコードを取得するには次のようにします。

user = User.find(requested_id)

 このほかにも様々な方法があります。本記事の後半では、いろいろな参照の仕方や検索条件の指定の方法などを詳しく解説していきます。

保存済みのレコードの更新

 更新するには、まず対象となるモデルオブジェクトを取得してから、その属性を変更してsaveします。

user = User.find(requested_id)
user.name = ‘Jiro’
user.save

レコードの削除

 削除を行うには、まず対象となるオブジェクトを取得してから、destroyメソッドを呼びます。

user = User.find(requested_id)
user.destroy

 ActiveRecordの基本操作は、このようにシンプルで直感的に扱えるものとなっています。

モデルクラスファイルの作成

 モデルクラスは、ActiveRecord::Baseを継承した派生クラスとしさえすれば、手でファイルを作り、一から自分で書いても構いません。しかし、以前の記事でも紹介したように、rails generateコマンド(rails g コマンド)を使えば、モデルクラスと関連するファイル一式を生成してくれるので、素早く開発が進められます。

 例えば、名前、Email、誕生日、会員番号を持つUserクラスを生成するには次のようにします。

> rails g model user name:string email:string birthday:date number:integer

 これによって、次のようなモデルクラスが作成されます。

class User < ActiveRecord::Base
end
[app/models/user.rb]

 このほかに、マイグレーションファイルと単体テストのためのファイル、単体テストで使うデータを記述するためのフィクスチャファイルが生成されます。

 このモデルクラスには、先ほどのrails gコマンドに与えたカラムの情報が反映されていません。これは、前述の通り、カラムと属性の対応付けがモデルクラス上の記述によってではなく、データベーススキーマ経由で行われるためです。では、gコマンドにカラム情報を与えた意味はどこにあるのでしょうか?

 実は、与えたカラム情報は、モデルクラスとともに生成される、データベーススキーマを変更するためのマイグレーションファイルやテスト系のファイルで利用されます。ActiveRecordを理解するには、このデータベーススキーマ部分を担当するマイグレーションの理解が欠かせません。そこで、続いてマイグレーションについて解説していきます。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。