Rails STI – 防止基类实例化

在基类实例化时,Rails STI情况中是否有任何方法抛出错误? 覆盖初始化将执行此操作,但随后会逐渐减少到子类。

谢谢

John Topley的答案实际上是错误的。 在基类中设置abstract_class = true实际上会导致子类自动停止设置其类型。 另外,除非你在基类中使用set_table_name,否则子类会抱怨它们的表不存在。

这是因为abstract_class = true的目的是在不使用STI时设置inheritance,并希望在ActiveRecord :: Base和一个或多个类之间的类层次结构中有一个抽象类(不由db表支持的类)模特class。

初始化raise是一个解决方案,同时将validates_presence_of:type添加到基类是一个解决方案。

注意如果你要覆盖初始化,你需要调用super:

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

你可以试试这个:

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

结果将是:

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

希望有所帮助

我经常更喜欢简单地将new类方法设为私有:

 class Base private_class_method :new end 

这种方式意外实例化Base类会触发错误,但仍然可以使用Base.send(:new)实例化它来为Base类编写测试。

在initialize函数中检查该类是否为STI基类。

虽然问题是你为什么要这么做? 尝试不同的设计似乎更有可能对您有所帮助。

您可以在基类中执行self.abstract_class = true ,以告诉ActiveRecord它是一个抽象类。