Ruby on Rails
Ereditarietà di una tabella singola
Ricerca…
introduzione
La STI (Single Table Inheritance) è un modello di progettazione basato sull'idea di salvare i dati di più modelli che ereditano tutti dallo stesso modello Base in un'unica tabella nel database.
Esempio di base
Per prima cosa abbiamo bisogno di una tabella per contenere i nostri dati
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
Quindi creiamo alcuni modelli
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
Quando Guest.create(name: 'Bob')
un Guest.create(name: 'Bob')
ActiveRecord lo tradurrà per creare una voce nella tabella Utenti con type: 'Guest'
.
Quando recuperi il record bob = User.where(name: 'Bob').first
l'oggetto restituito sarà un'istanza di Guest
, che può essere trattata con la forza come Utente con bob.becomes(User)
diventa è più utile quando si ha a che fare con partial condivisi o route / controller della superclasse anziché della sottoclasse.
Colonna ereditaria personalizzata
Per impostazione predefinita, il nome della classe del modello STI è memorizzato in una colonna di nome type
. Ma il suo nome può essere cambiato sovrascrivendo il valore inheritance_column
in una classe base. Per esempio:
class User < ActiveRecord::Base
self.inheritance_column = :entity_type # can be string as well
end
class Admin < User; end
La migrazione in questo caso avrà il seguente aspetto:
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
Quando Admin.create
, questo record verrà salvato nella tabella utenti con entity_type = "Admin"
Modello di rotaie con colonna di tipo e senza STI
Avendo type
colonna in un modello Rails senza invocare STI può essere ottenuto assegnando :_type_disabled
a inheritance_column
:
class User < ActiveRecord::Base
self.inheritance_column = :_type_disabled
end