2

我對Rails 3的使用Ruby和我實現了一個工作單表繼承這樣的:單表繼承是指一個子類有自己的領域

class User < ActiveRecord::Base 

    # Schema Information 
    # 
    # Table name: User 
    # 
    # id    : integer 
    # type   : string 
    # children_user_id: integer 

    ... 
end 

class UserAdmin < User 

    # Schema Information 
    # 
    # Table name: UserAdmin 
    # 
    # id    : integer 
    # special_field1 : string 
    # special_field2 : string 
    # ... 

    ... 
end 

class UserCommon < User 

    # Schema Information 
    # 
    # Table name: UserCommon 
    # 
    # id    : integer 
    # another_field1 : string 
    # another_field2 : string 
    # ... 

    ... 
end 

我想知道,在創建在User表中的記錄UserAdmin(或UserCommon記錄)運行以下

UserAdmin.create(:children_user_id => "1") 
# or UserCommon.create(:children_user_id => "1") 

能夠「自動地」以某種方式創建(可能是「滑軌路「!)在UserAdmin表(或UserCommon表)中也有一個新記錄,該表有其自己的字段(在數據庫級別,這些字段是列)。 我想這樣做是爲了「更好地處理」UserAdmin,因爲這個類具有UserCommon類的不同屬性。

如果可能的話,我怎麼能做到這一點(可能使用關聯模型報表,回調,多態性,...)你對這個問題有什麼建議嗎?

回答

7

單表繼承的事情是基於單個表模型,這並不奇怪,所以您不能使用不同的表具有不同的類。

通常,「Rails方式」將所有可能的字段捆綁到一個表中,並使用STI爲您處理數據映射和驗證問題。但是,它對應用程序隱藏的內容有限制,因爲通常定義的字段意味着它可以被綁定到該表的任何類使用。大多數人不認爲這是一個問題。

你可能想要做的是使該公司在根據用戶類型加入了一個記錄,例如:

class User < ActiveRecord::Base 
end 

class AdminUser < User 
    belongs_to :admin_profile 
end 

class CommonUser < User 
    belongs_to :common_profile 
end 

這就要求users表具有admin_profile_idcommon_profile_id的列,其中admin_profilescommon_profiles表格包含所需的附加字段。

根據需要,可以使用delegate方法將這些表中的屬性映射回基類。

將額外的字段移動到一個單獨的表中可能有助於劃分事物,但是這也意味着讀取會因要求的連接而變慢,並且由於一部分丟失或過期而導致記錄不一致的可能性增加。

通常,您可以將所有與用戶相關的字段加載到一個表中,即使這些字段中的許多字段不經常使用。一個NULL字段的存儲成本通常很低,除非有數百個這樣的字段,否則向開發人員提供的額外複雜性是最小的,要支付的代價要小於必須不斷創建和引用記錄。

+0

也許你在這句話之後忘了一些東西:「這些表中的屬性可以使用」映射回基類。不管怎麼說,還是要謝謝你。 – user502052 2011-05-05 00:22:56

+0

你是對的。我的意思是「可以使用委託方法映射回基類」 – tadman 2011-05-05 14:05:18