Activeレコードの基本
このガイドでは、Active Recordについて説明します。 このガイドを読むことで、次の事が学べるはずです。
- オブジェクト関連マッピング(ORM)とActiveレコードとはどんなもので、それらがどのようにRailsに使用されているか。
- Activeレコードのモデルを使ってどのようにデータベースに保存された関連するデータを操作するか。
- Activeレコードのスキーマの命名規則について
- データベースマイグレーション、検証、コールバックの設計概念について
- 1. Activeレコードとは何か?
- 2. Activeレコードでの「設定より規約」
- 3. Activeレコードモデルの作成
- 4. 命名規約の上書き
- 5. CRUD:データの読み込みと書き込み
- 6. 検証
- 7. コールバック
- 8. マイグレーション
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テーブル名は単語を分けるのにアンダースコアを使用しなければいけません。 例えば、
モデル/クラス | テーブル/スキーマ |
---|---|
Post | posts |
LineItem | line_items |
Deer | deer |
Mouse | mice |
Person | people |
2.2 スキーマの規約
Activeレコードは、DBテーブルのカラムのために、カラム用の命名規則を使用します。
また、Activeレコードインスタンスに、追加機能を作成するカラム名も存在します。
これらのカラム名はオプションですが、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
メソッドはオブジェクトを返し、更にデータベースへの保存も行います。
例えば、name
とoccupation
属性を持つUserモデルが与えられている場合、
下記のようにcreateメソッドが呼ばれると、新しいレコードを作成してデータベースに保存します。
user = User.create(name: "David", occupation: "Code Artist")
new
メソッドを使用すると、データベースには保存しないでオブジェクトのインスタンスだけを作成することが可能です。
user = User.new
user.name = "David"
user.occupation = "Code Artist"
user.saveを呼ぶと、データベースにレコードが保存されます。
ブロックを使用するとcreate
とnew
の両方で、ブロック内にて初期化された新しいオブジェクトが作られます。
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レコードは、それがデータベースに書き込まれる前に、モデルの状態を検証することができます。 様々なメソッドがあり、属性の値が空ではないか、一意で既にデータベースに存在しないか、特定のフォーマットに従っているかなどのチェックを行うことが可能です。
検証を考慮することは、データベースを使用する際に非常に重要で、
create
、save
、update
メソッドが実行された際に検証が失敗すると、
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マイグレーションガイドを参照してください。
© 2010 - 2017 STUDIO KINGDOM