DataMapper を使う (Single Table Inheritance)
DataMapper で STI を表現する場合は,以下のようにする.
class Person include DataMapper::Resource property :id, Serial property :name, String property :type, Discriminator ... end class Employee < Person property :dept, String # 所属 end class Customer < Person; end
作成されるテーブルは以下のようになる.
mysql> describe people; +-------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(50) | YES | | NULL | | | type | varchar(50) | NO | | NULL | | | dept | varchar(50) | YES | | NULL | | +-------+-------------+------+-----+---------+----------------+
DataMapper で STI を表現するときは,必ず property :type, Discriminator を定義しなければならない.
このカラムには,「実際にレコードを保存したクラス」のクラス名が自動的に保存される.
e = Employee.new e.name = 'krdlab' e.dept = '○○開発部' e.save # → type には 'Employee' が保存される
type カラムは,Employee.all や Customer.all で select の対象となるレコードの判別に利用される.
また,当然のことながら,Employee#dept を :nullable => false にすると,Customer の保存ができなくなってしまう.
モデル間に継承関係があり,それらのフィールドをダイレクトにマップしたい場合は便利.
- DataMapper misc
- Single Table Inheritance (STI)