Szukaj…


Wprowadzenie

Dziedziczenie pojedynczej tabeli (STI) to wzorzec projektowy oparty na idei zapisywania danych z wielu modeli dziedziczących z tego samego modelu podstawowego w jednej tabeli w bazie danych.

Podstawowy przykład

Najpierw potrzebujemy tabeli do przechowywania naszych danych

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

Następnie stwórzmy niektóre modele

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

Kiedy zrobisz Guest.create(name: 'Bob') ActiveRecord przetłumaczy to, aby utworzyć pozycję w tabeli Users z type: 'Guest' .

Po pobraniu rekordu bob = User.where(name: 'Bob').first zwracany obiekt będzie instancją Guest , którą można traktować siłą jako Użytkownik z bob.becomes(User)

staje się najbardziej użyteczny, gdy mamy do czynienia ze współdzielonymi częściami lub trasami / kontrolerami nadklasy zamiast podklasy.

Niestandardowa kolumna dziedziczenia

Domyślnie nazwa klasy modelu STI jest przechowywana w kolumnie o nazwie type . Ale jego nazwę można zmienić, zastępując wartość inheritance_column w klasie bazowej. Na przykład:

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

class Admin < User; end

Migracja w tym przypadku będzie wyglądać następująco:

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

Po Admin.create ten rekord zostanie zapisany w tabeli użytkowników za pomocą entity_type = "Admin"

Model szynowy z kolumną typu i bez STI

Posiadanie kolumny type w modelu Rails bez wywoływania STI można osiągnąć poprzez przypisanie :_type_disabled do inheritance_column :

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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow