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 の保存ができなくなってしまう.


モデル間に継承関係があり,それらのフィールドをダイレクトにマップしたい場合は便利.