单表继承引用具有自己字段的子类
我正在使用 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")
可以以某种方式“自动”创建(可能是“Rails Way”!)也在 UserAdmin
表(或 UserCommon
表)拥有自己的字段(在数据库级别,这些字段是列)。 我想这样做是为了“更好地处理”UserAdmin
,因为此类具有 UserCommon
类的不同且更多的属性。
如果可能,我该如何做到这一点(也许使用关联模型语句、回调、多态性等)? 您对这个问题有什么建议吗?
I am using Ruby on Rails 3 and I implemented a working Single Table Inheritance like the following:
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
I would like to know if, on creating an UserAdmin
record (or an UserCommon
record) in the User
table running the following
UserAdmin.create(:children_user_id => "1")
# or UserCommon.create(:children_user_id => "1")
it is possible to "automatically" create in someway (possibly the "Rails Way"!) a new record also in the UserAdmin
table (or UserCommon
table) that has its own fields (at the database level, those fields are columns). I would like to do that in order to "better handle" UserAdmin
because this class has different and more attributes of the UserCommon
class.
If it is possible, how can I do that (maybe using association model statements, callbacks, polymorphism, ...)? Do you have some advice on this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
单表继承的特点是它基于单表模型,这并不奇怪,因此您不能让不同的类使用不同的表。
通常,“Rails 方式”是将所需的所有可能字段捆绑到一个表中,并使用 STI 为您处理数据映射和验证问题。不过,它可以对应用程序隐藏的内容是有限的,因为通常定义的字段意味着它可以由绑定到该表的任何类使用。大多数人不认为这是一个问题。
您可能想要做的是根据用户类型创建一条记录,例如:
这需要
users
表具有admin_profile_id
和common_profile_id
列,其中admin_profiles
和common_profiles
表包含所需的附加字段。这些表中的属性可以根据需要使用
delegate
方法映射回基类。将额外的字段移到单独的表中可能有助于划分事物,但这也意味着读取速度会变慢,因为需要连接,并且由于一部分丢失或过时而导致记录不一致的可能性会增加。
一般来说,您可以将所有与用户相关的字段加载到单个表中,即使其中许多字段不经常使用。在方案中,NULL 字段的存储成本通常较低,除非有数百个此类字段,否则开发人员面临的额外复杂性很小,比必须不断成对创建和引用记录所付出的代价更小。
The thing with single table inheritance is it is based on a single table model, not surprisingly, so you can't have different classes using different tables.
Typically the "Rails Way" is to bundle together all the possible fields that are required into a single table and use STI to handle the data mapping and validation issues for you. There are limits on what it can hide from the application, though, as generally a field being defined means it's usable by any of the classes bound to that table. Most people do not consider this to be an issue.
What you probably want to do is make a record that's joined in depending on the user type, for instance:
This would require the
users
table having anadmin_profile_id
andcommon_profile_id
column where theadmin_profiles
andcommon_profiles
tables contain the required additional fields.The attributes in these tables can be mapped back into the base class using the
delegate
method as required.Moving the extra fields into a separate table may help compartmentalize things, but it also means reads will be slower because of the required join and the possibility of inconsistent records, due to one part being missing or out of date, is increased.
Generally you are okay loading all of the user-related fields into a single table even if many of these fields are not frequently used. The storage cost of a NULL field is typically low in the scheme of things and unless there are hundreds of these fields, the additional complexity exposed to the developer is minimal, a smaller price to pay than to have to create and reference records in pairs constantly.