ruby on rails - Impedire la STI quando si eredita da un modello di ActiveRecord




ruby-on-rails (2)

È possibile ottenere ciò disabilitando la inheritance_column per il modello, in questo modo:

class AnotherSection < Section
  # disable STI
  self.inheritance_column = :_type_disabled

end

Su Rails 3.2.6, ho una classe che eredita da ActiveRecord :: Base:

class Section < ActiveRecord::Base
  ...
end

Quando erediterò da questa classe, Rails presumerà che io voglia STI:

class AnotherSection < Section
   ..Rails assumes I have a type field, etc...
end

Voglio essere in grado di ereditare dalla classe Section e usare la sottoclasse come una sottoclasse Ruby normale, senza la magia STI di Rails.

C'è un modo per prevenire STI durante la sottoclasse da un modello ActiveRecord::Base ?


L'unica strategia pienamente supportata per archiviare l'ereditarietà su ActiveRecord è STI. Tuttavia, è possibile simulare un'eredità concreta delle class-table a proprio rischio. L'eredità concreta di class-table con la superclasse astratta funziona bene, come indicato dalla smathy.

MA ... Se ciò che si desidera è rendere AnotherSection solo una classe ordinaria (che non verrà mantenuta nel database), è possibile disabilitare la colonna discriminator (come suggerito da Veraticus). Tuttavia, se salvi AnotherSection , verrà mantenuto nella stessa tabella di Section e non sarai in grado di distinguerli. Inoltre, se usi AnotherSection per trovare una sezione , restituirà un AnotherSection , interrompendo l'istanza originale:

    #create a Section and saves it
    sect = Section.create()
    sect.save() 
    #retrieve the Section as a AnotherSection, breaking polymorphism... 
    sect = AnotherSection.find(sect.id)
    # another section is more than a section, it is inconsistent.

Se AnotherSection non è destinato a essere persistito, il percorso più sicuro per sovrascrivere le operazioni di persistenza, come save () e find ():

    class AnotherSection < Section
       # disable STI, as pointed by Veraticus
       self.inheritance_column = :_type_disabled
       # disable save and finding
       def save(*args)
         #exception? do nothing?
       end
       def find(*args)
         #exception? do nothing?
       end
       def find_by(*args)
         #exception? do nothing?
       end
       # this does not stops here! there is first, last, and even a forty_two finder method! not to mention associations...
    end

in poche parole, puoi farlo, ma NON DEVI FARE. Il rischio è alto. Dovresti prendere in considerazione un'altra opzione, come usare MIXIN invece dell'ereditarietà.







sti