ruby on rails webapp Rails STI: impedisce la classe base dall'istanza




software ruby on rails (4)

Puoi provare questo:

class BaseClass
  def initialize
    raise "BaseClass cannot be initialized" if self.class == BaseClass
  end
end

class ChildClass
end

il risultato sarà:

a = BaseClass.new  # Runtime Error
b = ChildClass.new # Ok

spero che sia d'aiuto

C'è un modo in una situazione STI di Rails per generare un errore quando la classe base è Istanziata? L'override dell'inizializzazione lo farà ma poi verrà scaricato nelle sottoclassi.

Grazie


Spesso preferisco semplicemente rendere privato il new metodo di classe con:

class Base
  private_class_method :new 
end

In questo modo l'istanziazione accidentale della classe Base genera un errore, ma è ancora possibile istanziarlo con Base.send(:new) per scrivere test per la classe Base.


La risposta di John Topley è in realtà sbagliata. L'impostazione di abstract_class = true nella classe base causerà effettivamente l'interruzione automatica dell'impostazione del tipo da parte delle classi figlie. Inoltre, a meno che tu non imposti set_table_name nella classe base, le classi figlie si lamenteranno che la loro tabella non esiste.

Questo perché lo scopo di abstract_class = true è di impostare l'ereditarietà quando NON si usa STI e si desidera avere una classe astratta (classe non supportata da una tabella db) nella propria gerarchia di classi tra ActiveRecord :: Base e uno o più classi modello.

Avere inizializzare il rilancio è una soluzione, aggiungendo anche validates_presence_of: type alla classe base è una soluzione.

Nota se fai l'override dell'inizializzazione, devi chiamare super:

def initialize(*args)
  raise "Cannot directly instantiate an AbstractUser" if self.class == AbstractUser
  super
end

Nella funzione initialize verificare che la classe sia la classe base STI.

Anche se la domanda è perché vorresti esattamente farlo? Sembra più probabile che provare un design diverso possa aiutarti di più.





ruby-on-rails