single rails belong association ruby-on-rails ruby sti

ruby-on-rails - association - belong to ruby on rails



Prevenir STI cuando se hereda de un modelo ActiveRecord (3)

La única estrategia totalmente compatible para almacenar la herencia en ActiveRecord es STI. Sin embargo, puede simular la herencia concreta de la tabla de clases bajo su propio riesgo. La herencia de mesa de clase concreta con superclase abstracta funciona bien, como lo señala la simpatía.

PERO ... Si lo que desea es hacer de AnotherSection solo una clase ordinaria (que no se mantendrá en la base de datos), puede desactivar la columna discriminadora (como lo sugiere Veraticus). Sin embargo, si guarda la Otra sección, se guardará en la misma tabla que la Sección y no podrá diferenciarlos. Además, si usa AnotherSection para encontrar una Sección , devolverá una AnotherSection , rompiendo la instanciación original:

#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.

Si no se pretende que AnotherSection sea ​​persistente, la ruta más segura es anular las operaciones de persistencia, como guardar () y buscar ():

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

en pocas palabras, puede hacer esto, pero NO DEBE. El riesgo es alto. Debe considerar otra opción, como usar MIXIN en lugar de la herencia.

En Rails 3.2.6, tengo una clase que hereda de ActiveRecord :: Base:

class Section < ActiveRecord::Base ... end

Cuando herede de esta clase, Rails asumirá que quiero STI:

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

Quiero poder heredar de la clase Section y usar la subclase como una subclase de Ruby normal, sin la magia Rails STI.

¿Hay una manera de prevenir STI cuando se hace una subclase de un modelo ActiveRecord::Base ?


La respuesta aceptada definitivamente funcionará, pero la forma recomendada (me atrevo a decir "correcto" :) es establecer abstract_class :

class Section < ActiveRecord::Base self.abstract_class = true end


Puede lograr esto deshabilitando la inheritance_column para el modelo, así:

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