子类化模型时的数据库和关系设计

时间:2009-07-13 16:35:53

标签: ruby-on-rails ruby database-design subclassing polymorphism

我有一个模型“任务”,它将HABTM很多“TaskTargets”。

然而,当谈到TaskTargets时,我正在编写基本的TaskTarget类,它是抽象的(尽可能在Rails中)。 TaskTarget将通过可以作为任务目标的任何事物的各种不同概念来进行子类化。所以说,软件子系统,客户网站,浴室等......

这里的类的设计相当简单,但是我遇到的问题是我将如何将它们联系在一起以及如何让rails操纵这些关系。

我的第一个想法是,我将有一个TaskTarget表,它将包含基本的公共字段(名称,描述......)。然后,它还将具有与实现类包装的数据类型相关的特定表的多态关系。 这意味着实现TaskTarget的类的一个实例的数据将在两个表中找到。

第二种方法是在TaskTarget的Task和子类之间创建多态HABTM关系,我认为我可以将表名TaskTarget重用于连接表。

选项#2我怀疑是最强大的,但也许我错过了一些东西。感谢您的帮助,当然我只是要求确保一次完成!

1 个答案:

答案 0 :(得分:4)

我认为Rails中可用的两种方法(很容易)是:

1)Single Table Inheritance:您创建一个TaskTarget表,其中包含每个子类可能需要的每个字段。然后,您还添加了一个存储类名的“类型”字段,Rails将为您完成其余的工作。有关详细信息,请参阅ActiveRecord api docs,尤其是“单表继承”部分。

2)Concrete Table Inheritance:基本TaskTarget类没有表。相反,只需为层次结构中的每个具体类创建一个表,只包含该类所需的字段。

第一个选项可以更轻松地执行“向我显示所有TaskTargets,无论子类如何”这样的操作,从而减少表的数量。它确实让人难以准确地说出一个子类可以做什么,而不是另一个,如果你有一个很多的TaskTargets,我想最终将它们全部放在一个表中可能是一个性能关注。

第二个选项使得更清晰的架构更容易阅读,并且每个类都可以像任何普通的ActiveRecord模型一样工作。但是,跨所有TaskTarget表加入可能很麻烦,尤其是在将来添加更多子类时。实现任何必要的多态关联也可能涉及一些额外的复杂性。

在您的情况下哪个选项更好将取决于您需要实施的操作以及数据集的特征。