Sök…


Introduktion

Single Table Inheritance (STI) är ett designmönster som bygger på idén att spara data från flera modeller som alla ärver från samma basmodell, till en enda tabell i databasen.

Grundläggande exempel

Först behöver vi en tabell för att hålla våra data

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

Låt oss sedan skapa några modeller

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

När du gör en Guest.create(name: 'Bob') kommer ActiveRecord att översätta detta för att skapa en post i användartabellen med type: 'Guest' .

När du hämtar posten bob = User.where(name: 'Bob').first Först kommer objektet som returneras att vara en instans av Guest , som kan tvingas behandlas som en bob.becomes(User) med bob.becomes(User)

blir är mest användbar när man hanterar delade partier eller rutter / kontroller av superklassen istället för underklassen.

Anpassad arvskolumn

Som standard STI modell klassnamn lagras i en kolumn som heter type . Men dess namn kan ändras genom att åsidosätta inheritance_column värde i en basklass. T.ex:

class User < ActiveRecord::Base
  self.inheritance_column = :entity_type # can be string as well
end

class Admin < User; end

Migrering i det här fallet ser ut enligt följande:

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

När du gör Admin.create här posten i användartabellen med entity_type = "Admin"

Rails modell med typ kolumn och utan STI

Med type kolumn i en Skenor modell utan att åberopa STI kan uppnås genom att tilldela :_type_disabled till inheritance_column :

class User < ActiveRecord::Base
  self.inheritance_column = :_type_disabled
end


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow