我正在使用Ruby on Rails 3,我实现了一个有效的单表继承,如下所示:
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
我想知道,在运行以下内容的UserAdmin
表格中创建UserCommon
记录(或User
记录)
UserAdmin.create(:children_user_id => "1")
# or UserCommon.create(:children_user_id => "1")
可以在UserAdmin
表(或UserCommon
表中)以某种方式“自动”创建(可能是“ Rails Way ”!)新记录它有自己的字段(在数据库级别,这些字段是列)。 我想这样做是为了“更好地处理”UserAdmin
,因为此类具有UserCommon
类的不同和更多属性。
如果有可能,我该怎么做(可能使用关联模型语句,回调,多态,......)? 你有吗?关于这个问题的建议?
答案 0 :(得分: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_id
和common_profile_id
列,其中admin_profiles
和common_profiles
表格包含所需的其他字段。
可以根据需要使用delegate
方法将这些表中的属性映射回基类。
将额外字段移动到单独的表中可能有助于划分事物,但这也意味着由于所需的连接而导致读取速度变慢,并且由于一个部分缺失或过期而导致记录不一致的可能性增加。
通常,您可以将所有与用户相关的字段加载到单个表中,即使不经常使用其中许多字段也是如此。事物方案中NULL字段的存储成本通常很低,除非有数百个这样的字段,否则暴露给开发人员的额外复杂性是最小的,要付出的代价要小于必须不断创建和引用记录的成本。