Activeレコードの基本

このガイドでは、Active Recordについて説明します。 このガイドを読むことで、次の事が学べるはずです。

  • オブジェクト関連マッピング(ORM)とActiveレコードとはどんなもので、それらがどのようにRailsに使用されているか。
  • Activeレコードのモデルを使ってどのようにデータベースに保存された関連するデータを操作するか。
  • Activeレコードのスキーマの命名規則について
  • データベースマイグレーション、検証、コールバックの設計概念について

1. Activeレコードとは何か?

ActiveレコードはMVCのM(モデル)であり、ビジネスデータとロジックに相当するシステムレイヤーです。 Activeレコードは、データベースへのデータ格納を必要とするビジネスオブジェクトの構築と使用を手助けしてくれます。 Activeレコードは、Activeレコード自身にORM(関連付け)の記述を行うという特徴を持ちます。

1.1 Active Recordの手法

Activeレコードは、Martin Fowler氏の書籍 Patterns of Enterprise Application Architecture にて、説明されています。 Activeレコードは、オブエジェクトのデータ保持とそのデータの操作を取り扱います。 Activeレコードは、データアクセスのロジックはオブジェクトの一部であることを保証し、 そのオブジェクトがデータベースへの読み書きの方法をユーザーに教育するという考えに基づいています。(翻訳に自信なし)

1.2 オブジェクト関連マッピング(ORM)

オブジェクト関連マッピング、一般的にORMとして略される仕組みは、 アプリケーションのオブジェクトとリレーショナルデータベースのテーブルを紐付けるテクニックです。 ORMを使用することで、プロパティとアプリケーション内のオブジェクトの関連性を簡単に保持出来るようになり、 SQLを直接書かずにデータベースにアクセスでき、データベースアクセス全般のコードを少なくすることが出来ます。

1.3 ORMフレームとしてのActiveレコード

Activeレコードはいつくかの仕組みを与えてくれますが、特に重要となる特徴は下記のとおりです。

  • モデルとそのデータを表す仕組み
  • モデル間の関連性を表す仕組み
  • 関連するモデルを通した階層の継承を表す仕組み
  • データベースに保存する前に、モデルを検証する仕組み
  • オブジェクト指向の手法でデータベース操作を実行する仕組み

2. Activeレコードでの「設定より規約」

他のプログラミング言語、またはフレームワークを使用してアプリケーションを書く際に、 多くの設定コードを書く必要があるかもしれません。 特に一般的なORMフレームワークに当てはまる事が多いです。 しかし、もしRailsの規則に従えば、Activeレコードのモデルの作成は非常に少ない設定コードで済ませる事が出来ます。 (全く設定をしないケースもあります。) これは、アプリケーションの設定を行う際に、全く同じ方法に多くの時間を費やすのであれば、デフォルトであるべきという考えです。 明示的な設定は、何らかの理由で規則に従うことができないような場合に必要とされるでしょう。

2.1 命名規則

デフォルトでは、Activeレコードはいくつかの命名規則から、 モデルと作成されているべきDBテーブルが、どのようにマッピングされているかを見つけ出します。 Railsは、開発者が名付けたモデルのクラス名を複数形にして各DBテーブルを探します。 そのため、Bookクラスであれば、DBテーブルの名前はbooksにすべきです。 Railsの複数形への変換機能は非常に強力で、複数形(単数形)への変換は、複数形が通常のものと例外の形式の単語、両方で機能します。 クラス名が複数の単語から構成される場合、モデルのクラス名はRubyの規約に従いキャメルケース(単語の先頭が1文字が大文字)形式を使用すべきで、 DBテーブル名は単語を分けるのにアンダースコアを使用しなければいけません。 例えば、

DBテーブル
複数形 - アンダースコアで単語を分けます(例: book_clubs)
モデルクラス
単数形 - 先頭の文字を大文字にすることで単語を分けます(例: BookClub)
モデル/クラス テーブル/スキーマ
Post posts
LineItem line_items
Deer deer
Mouse mice
Person people

2.2 スキーマの規約

Activeレコードは、DBテーブルのカラムのために、カラム用の命名規則を使用します。

外部キー
これらのフィールド名は、(単数形テーブル名)_idと命名すべきです。(例: item_id、order_id) このフィールドは、モデルで関連性を作成した際にActiveレコードを探す対象になります。
主キー
デフォルトでActiveレコードはidと名付けられた数値型のカラムをテーブルの主キーとして使用します。 Railsのマイグレーションを使用してテーブルを作成した場合、このカラムは自動的に生成されます。

また、Activeレコードインスタンスに、追加機能を作成するカラム名も存在します。

created_at
レコードが初めて作成される際に、自動的に現在の日時を取得して登録します。
updated_at
レコードが更新される度に、自動的に現在の日時を取得して登録・更新します。
lock_version
lock_version - Adds optimistic locking to a model.
type
モデルが、単一テーブルの継承を使用することを指定します。
(関連名)_type
ポリモーフィックな関連の型を格納します。
(テーブル名)_count
関連付けられたオブジェクトの数をキャッシュするのに使用します。 例えば、Postクラスのcomments_countカラムは、各postに紐づくCommentのインスタンス数をキャッシュします。

これらのカラム名はオプションですが、Activeレコードによって予約語とされています。 拡張機能が必要でない場合、これらの予約後の指定は避けてください。 例えば、typeは単一テーブル継承(STI)で使用される予約語です。 もし、STIを使用しない場合は似たキーワードである"context"など、使用するようにしてください。

3. Activeレコードモデルの作成

Activeレコードのモデルを作成するのは非常に簡単です。 ActiveRecord::Baseクラスのサブクラスを次のように書けば、準備完了です。

class Product < ActiveRecord::Base
end

これは、Productモデルを作成し、データベースのproductsテーブルにマッピングされます。 これにより、モデルのインスタンスの属性に、テーブルの各行のカラムもマッピングされます。 productsテーブルは、次のようなSQL文で作成されていると思います。

CREATE TABLE products (
   id int(11) NOT NULL auto_increment,
   name varchar(255),
   PRIMARY KEY  (id)
);

上記のテーブルの場合、下記のようにコードを書くことが出来ます。

p = Product.new
p.name = "Some Book"
puts p.name # "Some Book"

4. 命名規約の上書き

命名規約とは異なる名前を付ける必要がある場合、または過去に使用されていたデータベースを使用してRailsアプリケーションを作らなければいけない場合は、 どうすれば良いのでしょう? ご心配なく、デフォルトの規則を簡単に上書きすることが出来ます。

ActiveRecord::Base.table_name= メソッドを使用して、実際に使用するテーブル名を指定することが可能です。

class Product < ActiveRecord::Base
  self.table_name = "PRODUCT"
end

そうした場合、テスト定義内でset_fixture_classメソッドを使用して、 fixtures(クラス名.yml)を手動でクラス名を定義しなければいけません。

class FunnyJoke < ActiveSupport::TestCase
  set_fixture_class funny_jokes: 'Joke'
  fixtures :funny_jokes
  ...
end

また、ActiveRecord::Base.set_primary_keyメソッドを使用して、 テーブルの主キーとなるカラムを変更することも可能です。

class Product < ActiveRecord::Base
  set_primary_key "product_id"
end

5. CRUD:データの読み込みと書き込み

CRUDは、我々がデータを操作するCreate、Read、Update、Deleteの4つの動詞の頭字語です。 Activeレコードは、アプリケーションにテーブルに格納されているデータの読み込みと操作を行うメソッドを自動的に作成します。

5.1 Create

Activeレコードのオブジェクトは、ハッシュ、ブロック、またはオブジェクト作成後に属性を手動で設定することで、作成することが出来ます。 newメソッドは、新しいオブジェクトを返し、createメソッドはオブジェクトを返し、更にデータベースへの保存も行います。

例えば、nameoccupation属性を持つUserモデルが与えられている場合、 下記のようにcreateメソッドが呼ばれると、新しいレコードを作成してデータベースに保存します。

user = User.create(name: "David", occupation: "Code Artist")

newメソッドを使用すると、データベースには保存しないでオブジェクトのインスタンスだけを作成することが可能です。

user = User.new
user.name = "David"
user.occupation = "Code Artist"

user.saveを呼ぶと、データベースにレコードが保存されます。

ブロックを使用するとcreatenewの両方で、ブロック内にて初期化された新しいオブジェクトが作られます。

user = User.new do |u|
  u.name = "David"
  u.occupation = "Code Artist"
end

5.2 Read

Activeレコードは、データベース内のデータにアクセスするリッチなAPIを提供します。 下記は、Activeレコードによって提供されているデータアクセスのメソッドの使用例です。

# 全ユーザーのコレクションを返します
users = User.all
# 最初のユーザーを返します
user = User.first
# 名前がDavidのユーザーを返します
david = User.find_by_name('David')
# 名前がDavid、仕事がCode Artistの全ユーザーを探し、create_atの日付順でソートします。
users = User.where(name: 'David', occupation: 'Code Artist').order('created_at DESC')

Activeレコードモデルのクエリーについて更に学びたければ、 Activeレコードのクエリーインターフェースのガイドを参照してください。

5.3 Update

Activeレコードオブジェクトが取得されると、 その属性を修正することができ、データベースに保存することができる。

user = User.find_by_name('David')
user.name = 'Dave'
user.save

これを省略して、下記のように属性と値をハッシュマッピングで指定することが出来ます。

user = User.find_by_name('David')
user.update(name: 'Dave')

これは、一度にいくつかの属性を更新したい場合に非常に便利です。 一方で、もしレコードをまとめて更新したいような場合はクラスメソッドのupdate_allが便利です。

User.update_all "max_login_attempts = 3, must_change_password = 'true'"

5.4 Delete

同様に、取得したActiveレコードのオブジェクトをdestroyメソッドで、データベースから削除することが出来ます。

user = User.find_by_name('David')
user.destroy

6. 検証

Activeレコードは、それがデータベースに書き込まれる前に、モデルの状態を検証することができます。 様々なメソッドがあり、属性の値が空ではないか、一意で既にデータベースに存在しないか、特定のフォーマットに従っているかなどのチェックを行うことが可能です。

検証を考慮することは、データベースを使用する際に非常に重要で、 createsaveupdateメソッドが実行された際に検証が失敗すると、 falseを返し、データベースへの実際の処理は行われません。 これらの感嘆符付き(create!save!update!)の厳格なメソッドは、 検証が失敗するとActiveRecord::RecordInvalid例外を発生させます。 下記はその例になります。

class User < ActiveRecord::Base
  validates :name, presence: true
end

User.create  # => false
User.create! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank

検証について更に詳しく学びたければ、 Activeレコードの検証 のガイドを参照してください。

7. コールバック

Activeレコードのコールバックは、モデルのライフサイクルでの決まったイベントに対し、任意のコードを実行するようにしてくれます。 レコードの作成時、更新時、削除時のようなイベントが発生したい際に、実行するコードをモデルの振る舞いとして追加することができます。 コールバックについて、更に詳しく学びたければ、 Activeレコードのコールバックを参照してください。

8. マイグレーション

Railsはマイグレーション(migration)と呼ばれる、データベーススキーマにマッピングするためのドメイン特化言語を提供します。 マイグレーションは、rakeを使用したActiveレコードのサポートによって、データベースに対して実行されるファイル内に記述されます。 これは、テーブルを作成するマイグレーションです。

class CreatePublications < ActiveRecord::Migration
  def change
    create_table :publications do |t|
      t.string :title
      t.text :description
      t.references :publication_type
      t.integer :publisher_id
      t.string :publisher_type
      t.boolean :single_issue

      t.timestamps
    end
    add_index :publications, :publication_type_id
  end
end

Railsはデータベースに適用されたファイルの足跡を保持し、ロールバック機能を提供します。 実際に、rake db:migrateでテーブルを作成し、rake db:rollbackでロールバックします。

上記のコードは特定のデータベースに依存せず、MySQL、PostgreSQL、Oracle、その他のデータベースで実行される事に注意してください。 マイグレーションについて更に詳しく学びたければ、 ActiveレコードのDBマイグレーションガイドを参照してください。

 Back to top

© 2010 - 2017 STUDIO KINGDOM