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