LoginSignup
5
5

More than 5 years have passed since last update.

Active Record Basicsの日本語訳

Posted at

原文

もっといい翻訳

注意

英語の勉強も兼ねて訳しながら勉強しながら訳したものです。
一部英文がそのまま残っていますがどう訳せばよいのか分からなかったものです。

Active Record Basics

このガイドはActiveRecordの解説を行っています。
このガイドを読むとあなたは次のようなことを理解できます。

  • どのようなオブジェクトの参照、マッピングがActive RecordにありそれがRailsでどのように使われるのか。
  • ActiveRecordがModel-View-Controllerの中にどのように組み込まれるのか
  • リレーショナルデータベースに格納されたデータをActiveRecordを利用してどのように操作を行うのか
  • ActiveRecordでのスキーマの命名規則
  • データベースのマイグレーションやデータのバリデーションとcallbackの概念

1. ActiveRecordとは?

ActiveRecordはMVCのうちのM(Model)に当たり、ビジネスデータとビジネスロジックを担当する部分です。
ActiveRecordはデータベースに永続的に保存するようなビジネスオブジェクトの作成と利用を容易にします。
これはそれ自体がオブジェクトリレーショナルマッピングシステムの説明となるようなActiveRecordパターンを実装したものです。

1.1. ActiveRecordパターン

Active RecordはMartin Fowlerによって彼の著書であるEnterprise Application Architectureで説明されました。
AcriveRecordはデータの永続化や様々な操作を行う手段を提供します。
Active Record takes the opinion that ensuring data access logic as part of the object will educate users of that object on how to write to and read from the database.

1.2. オブジェクト関係マッピング(Object-relational mapping)

オブジェクト関係マッピングはよくORMという略語で呼ばれる、アプリケーションの様々なオブジェクトとデータベースのテーブルの関係性を管理するシステムです。
ORMを利用すると、データベースに対する操作をSQLを利用すること無くオブジェクトのプロパティや関連性を利用することで容易に保存・検索を行うことが出来ます。

1.3. ORMフレームワークとしてのActiveRecord

ActiveRecordは数々の機構を提供しますが、特に重要な機能は次のような物があります。

  • データをモデルとして表現する
  • 表現されたモデル同士の関連性を表現する
  • モデルの関連性を利用して、継承関係-階層関係を表現する
  • データベースへ保存する前にデータのバリデーションを行う
  • オブジェクト指向的な方法でデータベースの操作が行える

2. ActiveRecordでの設定より規約

他の開発言語やフレームワークを利用してアプリケーションを作る際に、多くの設定を書くことになっていたかもしれません。
これは一般的なORMフレームワークでも当てはまります。
しかしながら、あなたがRailsの規約に沿った開発を行っている場合、ActiveRecordのモデルを作成する時、とても少ない設定(もしかしたら一切の設定も必要ないかもしれません)で行えます。
これは、あなたが規約に沿ったアプリケーションを開発した場合の設定がデフォルトの設定でなければならないという考えに基づいてます。
このため、明示的な設定が必要になった場合、それは規約に沿った開発を行えない部分という事になります。

2.1. 命名規則

初期設定では、ActiveRecordはモデルとデータベースのテーブルの関係性を表現するためにいくつかの命名規則を使っています。
Railsはモデルのクラス名を複数形にしてテーブル名とします。
このため、Bookクラスはデータベースのテーブル名はbooksとなります。
Railsの複数形化を行う機能はとてもパワフルで、複数形化(又は単数形化)を双方向に、規則的・不規則的な単語を問わずに行うことが出来ます。
クラス名が2つ以上の単語で構成されている場合、モデルクラスの命名規則はRubyの命名規則に従いキャメルケースを利用します。
このようなモデルの時、データベースのテーブル名は単語の区切りにアンダースコア[_]が利用されます。
キャメルケースを利用して、

例:

  • データベースのテーブル名 - 単語がアンダースコアで区切られる (e.g., book_clubs).
  • モデルクラス名 - 各単語の先頭が大文字 (e.g., BookClub).
Model/Class Table/Schema
Article articles
LineItem line_items
Deer deers
Mouse mice
Person people

2.2. スキーマの規則

ActiveRecordはデータベーステーブルのカラムにもそのカラムの関連性により命名規則があります。

  • 外部キー(FK) - 外部キーは[単数形のテーブル名_id]のような命名を行う必要が有ります。このフィールドがあるとActiveRecordはモデル間の関連性を作成します。
  • 主キー(PK) - ActiveRecordでは標準でidというinteger型のカラムをテーブルのプライマリキーとます。ActiveRecordを利用してマイグレーションを行った場合このカラムは自動的に作成されます。

ActiveRecordではオプションのカラムとして、いくつかの特別な意味を持ったカラム名があります。
例:

  • create_at - レコードが最初に作成された時に自動的にその日時が保存されます。
  • update_at - レコードが更新された時に自動的にその日時が保存されます。
  • lock_version - モデルに楽観的ロックを追加します
  • type - シングルテーブル継承を利用することを指定します
  • (association_name)_type - Stores the type for polymorphic associations.
  • (テーブル名)_count - 関連するオブジェクトの数がキャッシュされます。
    例えばArticleクラスにcomments_countカラムを作成した場合、各記事がどれだけのコメントを持つかコメント数が格納されます。

これらの列はオプションですが、ActiveRecordによって予約されています。これらの機能を利用しない場合は、これらの名称を利用しないようにして下さい。例えばtypeはシングルテーブル継承のために予約されています。しかしシングルテーブル継承を使いたいのではない(普通のカラムとして使いたい)場合はよく似た"context"等のキーワードを使いモデリングを行って下さい。

3. ActiveRecordモデルを作成しよう

ActiveRecordモデルを作成することはとても簡単です。
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

If you do so, you will have to define manually the class name that is hosting the fixtures (class_name.yml) using the set_fixture_class method in your test definition:

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

また、プライマリキーを別の任意の名前にすることもActiveRecord::Base.primary_key=メソッドを利用することで行えます

class Product < ActiveRecord::Base
  self.primary_key = "product_id"
end

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

CRUDとは4つのデータに対する操作の頭文字を組み合わせた略語です:作成(Create) 読込(Read) 更新(Update) 削除(Delete)
ActiveRecordはアプリケーションからこれらの操作をテーブルに対して行えるようなメソッドを自動的に作成します。

5.1. Create

ActiveRecordオブジェクトはハッシュ、ブロック構文、属性への手動での追加等で作成することが出来ます。
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

ActiveRecordはデータベースからデータを取得するための様々なAPIを提供します。
以下はActiveRecordが持つアクセスメソッドの幾つかの例です。

# 全てのユーザーのコレクションを返す
users = User.all
# 最初のユーザーのオブジェクトを返す
user = User.first
# Davidという名前の最初のユーザーを返す
david = User.find_by(name: 'David')
# Davidという名前で職業がCodeArtistなユーザーを作成日時降順でソートして取得する
users = User.where(name: 'David', occupation: 'Code Artist').order('created_at DESC')

ActiveRecordの更に詳しいクエリの情報はActive Record Query Interface Guideを参照して下さい。

5.3. Update

ActiveRecordオブジェクトを取得し、その属性を変更することでデータベースの更新を行うことが出来ます。

user = User.find_by(name: 'David')
user.name = 'Dave'
user.save

ハッシュを利用してname属性と値を渡すことで短く書くことも出来ます

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

更新と同様に取得したActiveRecordオブジェクトを利用して、データベースから削除することが出来ます。

user = User.find_by(name: 'David')
user.destroy

6. Validations

ActiveRecordはデータベースに書き込む前にモデルの検証を行うことが出来ます。
用意された幾つかの方法を使ってモデルの検証を行うことが出来ます。
例えば値が空では無いか、既にデータベース上に同じ値が存在しないか、決められたフォーマットに沿っているか等です。

バリデーションはデータベースに保存する上でとても重要な問題です。
もしバリデーションに通らなかった時はsaveやupdateが行った時にfalseが返されデータベースへの永続化は実行されません。
もし破壊的メソッド(save!やupdate!)を使った場合はfalseより更に厳しいActiveRecord::RecordInvalidがバリデーションの失敗時に返されます。簡単に説明すると次のようになります

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

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

更に詳しくバリデーションについて学ぶにはActive Record Validations guideを参照して下さい

7. コールバック(Callbacks)

ActiveRecordCallbacksはあなたが作成したモデルのライフサイクルにおける特定のイベントに対してコードをアタッチすることが出来ます。例えば新しいレコードを作成する時、更新する時、削除する時等に、透過的に実行することが出来ます。
コールバックの詳しい情報はActive Record Callbacks guideで学ぶことが出来ます。

8 マイグレーション(Migrations)

Railsはマイグレーションと呼ばれるデータベースを管理するためのDSL(domain-specific language)を提供します。
マイグレーションはRakeを利用して実行するファイルとして保存されます。これはActiveRecordがサポートする様々なデータベースで実行出来ます。
これはテーブルを作成するマイグレーションです

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 null: false
    end
    add_index :publications, :publication_type_id
  end
end

Railsはこのようなファイルがデータベースに対して実行されたことを記録しており、コミット及びロールバックといった機能を提供します。
もしテーブルを作成したい場合はrake db:migrate 取り消したい場合は rake db:rollbackを使うことが出来ます。

上記のコードはデータベースに依存しないことに注意してください。これはMySQL,PostgreSQL,Oracleやその他で実行することが出来ます。更に詳しいマイグレーションの情報はActive Record Migrations guideを参照して下さい。

さいごに

素晴らしい翻訳ドキュメントがコミュニティで整備され公開されてるのをこの翻訳を初めて少しして見つけました。
英語の勉強になったからいいんよもう・・・・英語の勉強もっとするんよ。。。

5
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5