在Rails中实现多表继承的最干法是什么?

时间:2019-05-20 05:56:26

标签: ruby-on-rails ruby

我的应用程序中有几个表,它们共享大多数列,我在一个模型中编写了所有验证,并试图使所有其他模型都从该模型继承,但出现ActiveRecord::SublassNotFound错误。

这是我的模型的代码:

hospial.rb

class Hospital < ActiveRecord::Base

    validates :cnes, presence: true, numericality: true
    validates :name, presence: true, length: { maximum: 80 }
    validates :address, presence: true, length: { maximum: 50 }
    validates :neighborhood, presence: true, length: { maximum: 30 }
    validates :phone, presence: true, length: { in: 10..25 }
    validates :latitude, :longitude, presence: true, length: { maximum: 20 }
    validates :type, presence: true

pharmacy.rb

class Pharmacy < Hospital
   self.table_name = 'pharmacies' 
end

这两个表的列完全相同,我选择使用MTI来赋予数据库更大的可伸缩性,因为药房和医院都将对多个模型都具有STI。

这是我得到的错误:

ActiveRecord::SubclassNotFound:
       Invalid single-table inheritance type: Hospital is not a subclass of Pharmacy

我想重用两个模型的验证和打算实现的一些方法。

2 个答案:

答案 0 :(得分:2)

如果使用单独的表,则不应将其他模型用作子类。在这种情况下,您只想从ActiveRecord::Base继承。如果要共享验证,可以将它们放在模块中,并在两个模型中都需要。

当然,您也可以转到真正的STI,但是在那种情况下,您需要向单个表中添加一个type列。在那种情况下,您可以从Hospital继承,但是最好从Institute继承,让Hospital也从该Base类继承。

class Institute < ActiveRecord::Base
  # put your validations here
end

class Hospital < Institute
end

class Pharmacy < Institute 
end

编辑:如果您想使用MTI ...请参见以下答案,以了解如何设置验证Mixins:https://stackoverflow.com/a/11372578/891359

答案 1 :(得分:1)

您需要的是一个抽象类:

class Hospital < ActiveRecord::Base
  self.abstract_class = true

  # validations...
end

然后从子类中删除表名。