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


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow