サーチ…


前書き

単一表継承(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_disabledinheritance_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