Rails は Webアプリケーションフレームワークです。MVC (Model, View, Controller) にレイヤを分離しています。
Rails の MVC にはそれぞれ代表するライブラリ(フレームワーク)があります。 Active Record はその一つです。
- Rails のライブラリの
gemspec
のsummary
を抜粋- Models
- Active Record
- Object-relational mapper framework (part of Rails).
- Active Record
- Views
- Action View
- Rendering framework putting the V in MVC (part of Rails).
- Action View
- Controllers
- Action Controller (Action Pack)
- Web-flow and rendering framework putting the VC in MVC (part of Rails).
- Action Controller (Action Pack)
- Models
Active Record の Object-relational mapper ってなんでしょう!
簡単に説明すると Ruby on Rails の Ruby はオブジェクト指向スクリプト言語ですね。
オブジェクト指向(Object-oriented)は実世界をコンピュータの世界に写像するパラダイムです。
実世界のモノは状態を保有します。それを写像したオブジェクトは永続化の必要性が生じます。
永続化にはリレーショナルデータベース(RDB)が広く利用されていますね。
でも RDB の基礎となったリレーショナルモデルは数学的なパラダイムなのです。
このパラダイムの違いでインピーダンス・ミスマッチが存在します。
そこでオブジェクトをリレーショナルデータベースにマッピングすることで
親和性を改善する手法が Object-relational mapping (ORM) です。
そのライブラリが Active Record (Object-relational mapping in Rails) です。
Active Record Pattern
README に Patterns of Enterprise Application Architecture :Martin Fowler (著) の Active Record の実装と書いています。
An object that wraps a row in a database table or view,
encapsulates the database access, and adds domain logic on that data.
訳してみました。
データベースのテーブルまたはビューの行をオブジェクトにまとわせる,
データベースの読み書きをカプセル化し, そのデータにドメインロジックを追加する.
データベースで 1件
のデータはレコードと呼ばれます。1件
のレコードでオブジェクトが生成されて
そのオブジェクトにはデータ構造とデータ、さらに振る舞いを保有するデザインパターンです。
データ構造とデータに振る舞いを一体化した、能動的なレコードなので Active Record でしょうか。
Object-oriented Modeling
Object-oriented Modeling and Design :James Rumbaugh (著), Michael Blaha (著), William Premerlani (著) にオブジェクト指向の定義が記されています。
データ構造と振る舞いが一体となったオブジェクトの集まりとしてソフトウエアを組織化すること
Active Record を利用することでオブジェクト指向の定義に沿える Convention over Configuration でしょうか。
Object-relational mapping
ORM は ActiveRecord::Base のクラスを継承することでマッピングが得られます。
-
1つ
のテーブルが1つ
のクラスに対応します。 -
1つ
のレコードが1つ
のインスタンスに対応します。
Object | Relational |
---|---|
Class | Table |
Instance | Record |
Attribute | Column |
Value | Field |
Message | Select, Update, ... |
Layered architecture
- 永続化クラス(ActiveRecord::Base)から派生してドメインクラスを作ります。
- ドメインクラスには抽象化した関心事の責務を記述します。
ドメインクラス <-> 永続化クラス <-> データベース
Example
2行でデータベースを操作するだけのドメインクラスを記述できます。
(Rails 5 では ActiveRecord::Base
が ApplicationRecord
になります。)
class Product < ActiveRecord::Base
end
クラスメソッドやインスタンスメソッドで SQL が実行されます。
product = Product.find(1) # SELECT * FROM products WHERE id = 1 LIMIT 1
product.name = "bouquet" #
product.save # UPDATE products SET name = "bouquet" WHERE id = 1
DSL でドメインクラスの関連やフィールドのバリデーションを定義します。
- has_many: 関連付け(アソシエーション)
- composed_of: 値オブジェクトを集約(アグリゲート)
- validates: フィールドを検証(バリデーション)
class Customer < ActiveRecord::Base
has_many :sales_orders
has_many :products, through: :sales_orders
composed_of :address, mapping: [%w(address_street street), %w(address_city city)]
validates :name, presence: true
end
class Address
attr_reader :street, :city
def initialize(street, city)
@street, @city= street, city
end
end
Rails の Active Record でソフトウェアを楽しく、そして速く開発しましょう!
Tips
Active Record は 1つ
のテーブルが 1つ
のクラスに対応する規約です。
単純な原理なのでクラス(テーブル)の責務を適切に分離することになるでしょう。
複雑なものには向かないかもしれませんが、簡単なものには向いています。
(複雑なことを簡単にすることで対応の幅は広がりますが、難しいことです。)
ただ簡単であることは大切で、開発者は複雑だったり理解できなかったりすると
継続的な開発を止めて作り直したくなります。でも単純で簡単だと理解してくれる可能性は高くなります。
ドメインエキスパートもドメインクラスのコードが読めるくらいが理想ですね。