Ruby on Rails
Dziedziczenie pojedynczej tabeli
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