単一テーブル継承 (Single Table Inheritance) の上手な扱い方
Railsの単一テーブル継承 (Single Table Inheritance) を使うと、ActiveRecordではtypeカラムがnilでないオブジェクトのクラスはtypeを元に判定されます。
単一テーブル継承 (Single Table Inheritance) を使うには、テーブル定義時にtypeというカラムを定義します。
-
class CreatePeople <ActiveRecord::Migration
-
def self.up
-
create_table :people do |t|
-
t.column :name, :string
-
:
-
t.column :type, :string
-
end
-
end
-
-
def self.down
-
drop_table :people
-
end
-
end
ここでpeopleテーブルに対応したPersonというベースとなくクラスを以下のように定義したとします。
-
class Person <ActiveRecord::Base
-
# edit here
-
end
こうするとPersonを継承したモデルは全てpeopleテーブルに保存され、typeカラムに各モデルのクラス名が入ります。
(単一テーブル継承の詳しい使い方はこちらをご覧ください:「Railsで単一テーブル継承(Single Table Inheritance) | 京の路」)
ここで、実際には利用しない中間クラスを挟むと、Personのサブクラスへのアクセスをそのクラスに集中させることで、各サブクラスのクラスを意識することなく扱うことができるようになります。
例えばExtendedPersonクラスを中間クラスとして挟み、ExtendedPersonを継承したMale / Femaleというモデルを定義します。
-
class Student <Person
-
# edit here
-
end
-
-
class MaleStudent <Student
-
def call_name
-
"#{name}くん"
-
end
-
end
-
-
class FemaleStudent <Student
-
def call_name
-
"#{name}さん"
-
end
-
end
こうすると、以下のようにMale / Femaleを意識することなく、これらのインスタンスを扱えます。
-
MaleStudent.create(:name => "タロウ")
-
MaleStudent.create(:name => "ハナコ")
-
-
students = Student.find(:all)
-
students.each do |student|
-
student.call_name
-
end
-
-
# =>
-
# タロウくん
-
# ハナコさん
もうこんなことしなくていい。
-
male_students = MaleStudent.find(:all)
-
female_students = FemaleStudent.find(:all)
-
-
male_students.each do |male_student|
-
male_student.call_name
-
end
-
-
female_students.each do |female_student|
-
female_student.call_name
-
end
単一テーブル継承で多数のクラスを1つのテーブルに集中させる場合は、これでソースがかなり奇麗になりますよ♪












この記事がお役に立ちましたら、一言コメントもらえると嬉しいですm_ _m