5

我正在開發一個非常大的Rails應用程序。我們最初沒有使用過多的繼承,但我們從一位顧問那裏獲得了一些開眼界的經驗,並且正在考慮重構我們的一些模型。有多少班級太多? Rails STI

我們有下面的模式有很多在我們的應用:

class Project < ActiveRecord::Base 
    has_many :graph_settings 
end 

class GraphType < ActiveRecord::Base 
    has_many :graph_settings 
    #graph type specific settings (units, labels, etc) stored in DB and very infrequently updated. 
end 

class GraphSetting < ActiveRecord::Base 
    belongs_to :graph_type 
    belongs_to :project 
    # Project implementation of graph type specific settings (y_min, y_max) also stored in db. 
end 

這也導致在視圖中,幫手和在GraphSetting模型本身噸條件句。這一切都不好。

一個簡單的重構,我們得到有利於擺脫GraphType的使用結構更是這樣的:

class Graph < ActiveRecord::Base 
    belongs_to :project 
    # Generic methods and settings 
end 

class SpecificGraph < Graph 
    # Default methods and settings hard coded 
    # Project implementation specific details stored in db. 
end 

現在,這使我感覺良好,簡化了測試,消除條件語句,使後來的國際化更容易。但是我們只有15到30個圖表。

我們有一個非常相似的模型(以複雜的形式作爲例子),可能接近100種不同的'類型',並且可能會加倍。他們都會有他們繼承的關係和方法,有些需要重寫更多的方法,然後是其他方法。它看起來很完美,但很多人看起來很多。

200個STI課程對很多?我們應該看到另一種模式嗎?

感謝您的任何智慧,我會回答任何問題。

回答

4

如果差異只在班級的行爲上,那麼我認爲它不應該是一個問題,這是STI的一個很好的候選人。 (請注意,我從來沒有嘗試過這麼多的子類)

但是,如果你的200個STI類每個都有一些獨特的屬性,你需要在主表中有很多額外的數據庫列,它們是NULL ,99.5%的時間。這可能是非常低效的。

要創造這樣的「多表繼承」,我已經成功之前完成是用一個小元編程到其它表的唯一的每個類細節關聯:

class SpecificGraph < Graph 
    include SpecificGraphDetail::MTI 
end 

class SpecificGraphDetail < ActiveRecord::Base 
    module MTI 
    def self.included(base) 
     base.class_eval do 
     has_one :specific_graph_detail, :foreign_key => 'graph_id', :dependent => :destroy 
     delegate :extra_column, :extra_column=, :to => :specific_graph_detail 
     end 
    end 
    end 
end 

代表團手段您可以訪問關聯的明細字段,就好像它們直接在模型上一樣,而不是通過specific_graph_detail關聯,並且出於所有意圖和目的,它「看起來」像這些只是額外的列。

對於只需要在主表中添加額外列的情況,您必須權衡這些額外的細節表。這將決定是否使用STI或使用關聯表的解決方案,例如上面的解決方案。

+0

感謝您的回覆。在這一點上,我不認爲我們會有很多(如果有的話)數據庫中的空值,因爲屬性是相同的,只是值和方法會改變。 (例如它如何返回圖形的數據來繪製)。 如果我們結束了空字段(可能不是這個特定的實例,但其他類似的實例),我一定會牢記這一點。 – 2010-09-09 16:13:19

+0

還有另一種類似的方法http://stackoverflow.com/questions/1634668/multiple-table-inheritance-vs-single-table-inheritance-in-ruby-on-rails/1634734#1634734 – 2010-09-09 16:59:06