【问题标题】:Polymorphic STI setup多态性 STI 设置
【发布时间】:2011-03-05 05:07:08
【问题描述】:

我有一个广泛使用实体模型的应用。

在这个应用程序的过去版本中(正在重写,当前版本是 PHP),这是用一个表继承建模的,基本上有两个相同的模型。

  • 一个模型是实体,它与项目相关联并且有多种类型(客户端、请求者、提供者等)。

  • 另一个模型是地址簿,它与实体大部分相同,除了不同的表和模型名称以及一些仅地址簿字段(例如禁用)。

我们目前有一个关于 addressbook_id 的实体列,用于将项目实体映射回地址簿,或者我们尝试基于电子邮件地址进行映射失败。地址簿和实体之间的数据不会保持同步,也就是说,必须能够更新项目中的实体,而不会对地址簿中的数据产生任何影响(尽管我们也提供了更新地址簿的选项)。

不管怎样,实体有 4 或 5 种类型。它们具有大部分相同的字段(名字、姓氏、电子邮件、地址、电话等)。每个实体类型可能有 1 - 3 个字段,它们是唯一的,仅此而已。除此之外,当前应用中的实体可能是人或公司(同一个 STI 表,其中也有一个 company_name 字段)。

对于应用程序需要做的事情,能够轻松找到项目的所有实体(无论类型如何,无论他们是个人还是公司)是一种胜利。还能够轻松地在查询中加入实体,并在每个项目中搜索它们,赢了。

因此,我倾向于坚持 STI 模型并使其保持简单,并且由于每种类型共享 90% 的相同字段,因此不会造成太多浪费。但是,我很好奇是否有任何好的建议来处理地址簿和实体具有基本相同的模型,但将数据保存在单独的表中的整个问题。我已经考虑过多态关联如何提供帮助,但我认为这会使表结构更加复杂并可能会损害查询的性能(相当大的数据集,这些实体可能包含在列表视图中)。

但我真的不想这样结束......

class Entity

class Customer < Entity

class Addressbook

class AddressbookCustomer < Addressbook

etc...

不是很干,实体类型和子类型之间有共同的功能(例如,Entity 和 Addressbook 都有一个返回全名的 name 方法,而 Customer 和 AddressbookCustomer 都可能有一个 last_order 方法)。

当前数据只是存储在两个表中,地址簿和实体,它们都有一个类型列。但是,这是一个彻底的突破,因此不必保留旧表结构,但是从保持简单的角度来看,我确实喜欢这种结构。

有什么建议吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord


    【解决方案1】:

    我从未这样做过,但如果您想在所有“实体”之间共享代码,为什么不创建一个其他所有内容都继承自的基类:

    class OneClassToRuleThemAll < ActiveRecord::Base
      def name
      ...
    
    
    class Entity < OneClassToRuleThemAll
      set_table_name "entities"
    
    class AddressBook < OneClassToRuleThemAll
      set_table_name "address_books"
    

    这为您提供了一个共享方法的基类,但为您的继承树中的每个分支提供了单独的表。

    如果您不喜欢该解决方案,因为您仍想共享不属于 OneClassToRuleThemAll 的方法,但在树的更下方的表亲类之间共享,那么为什么不编写一个小模块来保存这些函数,例如last order,然后将该模块导入到需要这些函数的每个表亲类中?

    附:我什至不知道第一个示例是否可行,但我认为应该可行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多