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