Ruby on Rails
単一テーブル継承
サーチ…
前書き
単一表継承(STI)は、同じ基本モデルからすべて継承している複数のモデルのデータをデータベース内の単一の表に保存するという考え方に基づいた設計パターンです。
基本的な例
まず、データを保持するテーブルが必要です
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :password
t.string :type # <- This makes it an STI
t.timestamps
end
end
end
次にいくつかのモデルを作成させます
class User < ActiveRecord::Base
validates_presence_of :password
# This is a parent class. All shared logic goes here
end
class Admin < User
# Admins must have more secure passwords than regular users
# We can add it here
validates :custom_password_validation
end
class Guest < User
# Lets say that we have a guest type login.
# It has a static password that cannot be changed
validates_inclusion_of :password, in: ['guest_password']
end
Guest.create(name: 'Bob')
を実行すると、ActiveRecordはこれを翻訳して、 type: 'Guest'
のUsersテーブルにエントリを作成します。
レコードを取得すると、 bob = User.where(name: 'Bob').first
に返されるオブジェクトはGuest
インスタンスになりますbob.becomes(User)
持つUserとして強制的に扱うことができます。
は、サブクラスではなくスーパークラスの共有パーシャルまたはルート/コントローラを扱うときに最も便利です。
カスタム継承列
デフォルトでは、STIモデルクラス名はtype
という名前の列に格納されます。しかし、その名前は、基本クラスのinheritance_column
値をオーバーライドすることで変更できます。例えば:
class User < ActiveRecord::Base
self.inheritance_column = :entity_type # can be string as well
end
class Admin < User; end
この場合の移行は次のようになります。
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :password
t.string :entity_type
t.timestamps
end
end
end
Admin.create
を実行Admin.create
、このレコードは、 entity_type = "Admin"
usersテーブルに保存されますentity_type = "Admin"
タイプ列とSTIなしのRailsモデル
STIを呼び出さずにRailsモデルに列をtype
すると、 :_type_disabled
をinheritance_column
割り当てることで実現できます。
class User < ActiveRecord::Base
self.inheritance_column = :_type_disabled
end
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow