单表继承引用具有自己字段的子类

发布于 2024-11-05 04:32:23 字数 1194 浏览 8 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萤火眠眠 2024-11-12 04:32:23

单表继承的特点是它基于单表模型,这并不奇怪,因此您不能让不同的类使用不同的表。

通常,“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 字段的存储成本通常较低,除非有数百个此类字段,否则开发人员面临的额外复杂性很小,比必须不断成对创建和引用记录所付出的代价更小。

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:

class User < ActiveRecord::Base
end

class AdminUser < User
  belongs_to :admin_profile
end

class CommonUser < User
  belongs_to :common_profile
end

This would require the users table having an admin_profile_id and common_profile_id column where the admin_profiles and common_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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文