Ruby on Rails
Herencia de una sola mesa
Buscar..
Introducción
La herencia de una sola tabla (STI) es un patrón de diseño que se basa en la idea de guardar los datos de varios modelos que se heredan del mismo modelo base, en una sola tabla en la base de datos.
Ejemplo basico
Primero necesitamos una tabla para guardar nuestros datos.
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
Entonces vamos a crear algunos modelos.
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
Cuando hagas un Guest.create(name: 'Bob')
ActiveRecord lo traducirá para crear una entrada en la tabla de Usuarios con el type: 'Guest'
.
Cuando recupera el registro bob = User.where(name: 'Bob').first
el objeto devuelto será una instancia de Guest
, que se puede tratar a la fuerza como un usuario con bob.becomes(User)
es más útil cuando se trata de parciales compartidos o rutas / controladores de la superclase en lugar de la subclase.
Columna de herencia personalizada
Por defecto, el nombre de la clase del modelo STI se almacena en una columna denominada type
. Pero su nombre se puede cambiar al reemplazar el valor de inheritance_column
en una clase base. P.ej:
class User < ActiveRecord::Base
self.inheritance_column = :entity_type # can be string as well
end
class Admin < User; end
La migración en este caso se verá como sigue:
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
Cuando haga Admin.create
, este registro se guardará en la tabla de usuarios con entity_type = "Admin"
Modelo de rieles con columna tipo y sin STI.
Tener type
columna en un modelo de rieles sin invocar STI se puede lograr mediante la asignación de :_type_disabled
a inheritance_column
:
class User < ActiveRecord::Base
self.inheritance_column = :_type_disabled
end