在Rails 3.2.6上,我有一个继承自ActiveRecord :: Base的类:
class Section < ActiveRecord::Base
...
end
当我从这个类继承时,Rails会假设我想要STI:
class AnotherSection < Section
..Rails assumes I have a type field, etc...
end
我希望能够从Section
类继承并使用子类作为普通的Ruby子类,而不使用Rails STI魔法。
在从ActiveRecord::Base
模型中进行子类化时,有没有办法阻止STI?
答案 0 :(得分:34)
您可以通过禁用模型的inheritance_column
来实现此目的,如下所示:
class AnotherSection < Section
# disable STI
self.inheritance_column = :_type_disabled
end
答案 1 :(得分:10)
接受的答案肯定会有效,但推荐的(我敢说“正确”:)方式是设置<activity
android:name=".MainActivity"
android:theme="@style/AppTheme"/>
:
abstract_class
答案 2 :(得分:1)
在ActiveRecord上存储继承的唯一完全支持的策略是STI。但是,您可以自行承担模拟具体类表继承的风险。具有抽象超类的具体类表继承工作正常,如smathy所指出的那样。
但是......如果您想要的是使 AnotherSection 只是一个普通的类(不会在数据库中保留),您可以禁用鉴别器列(如Veraticus所建议的那样)。但是,如果您保存 AnotherSection ,它将与Section保持在同一个表中,您将无法区分它们。此外,如果您使用 AnotherSection 来查找 Section ,它将返回 AnotherSection ,从而打破原始实例化:
#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.
如果 AnotherSection 不打算保留,那么它是覆盖持久性操作的最安全的路径,例如save()和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
简而言之,你可以做到这一点,但你应该这样做。风险很高。
您应该考虑另一个选项,例如使用MIXIN而不是继承。