2010-05-17 63 views
19

當基類實例化時,Rails STI情況下是否有任何方法拋出錯誤?重寫初始化會做到這一點,但隨後會逐漸下降到子類。Rails STI - 阻止基類實例化

謝謝

回答

0

在初始化函數檢查該類是STI基類。

雖然問題是你爲什麼要這麼做?看起來更有可能嘗試一種不同的設計可能會對您有所幫助。

-4

你可以在基類中做self.abstract_class = true告訴ActiveRecord它是一個抽象類。

3

你可以試試這個:

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 

希望幫助

+1

由於BaseClass可能會從ActiveRecord :: Base下降,初始化應該可能會調用super。 – Douglas 2014-01-18 17:33:56

40

由約翰·託普利答案其實是錯誤的。在基類中設置abstract_class = true實際上會導致子類自動停止設置其類型。另外,除非你在基類中使用set_table_name,否則子類將會抱怨他們的表不存在。

這是因爲abstract_class = true的目的是在不使用STI時設置繼承,並且希望在ActiveRecord :: Base之間的類層次結構中有一個抽象類(類不支持db表)和一個或多個模型類。

初始化raise是一種解決方案,同時向基類添加validates_presence_of:type是一個解決方案。

注意如果覆蓋初始化,你需要調用超:

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

爲什麼這個答案不在答案的頂部?它位於0票和另一票被刪除的答案下面。 – 2016-09-15 19:34:47

0

我經常喜歡簡單地讓new類方法的私人用:

class Base 
    private_class_method :new 
end 

這樣的意外實例基類觸發錯誤,但仍可以使用Base.send(:new)實例化它,爲基類編寫測試。