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 переведет это, чтобы создать запись в таблице Users с type: 'Guest'
.
Когда вы извлекаете запись bob = User.where(name: 'Bob').first
возвращаемый объект будет экземпляром Guest
, который может быть принудительно обработан как Пользователь с bob.becomes(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
, эта запись будет сохранена в таблице users с entity_type = "Admin"
Модель Rails с столбцом типа и без ИППП
Наличие столбца type
в модели Rails без вызова STI может быть достигнуто путем назначения :_type_disabled
для inheritance_column
:
class User < ActiveRecord::Base
self.inheritance_column = :_type_disabled
end