单表inheritance和在Rails中使用它的地方

我陷入了一个奇怪的devise问题,

我正在研究两种型材型号,

  • 用户configuration文件(属于用户)
  • 其他人在现场维护为“机器人”(不属于任何人)

这两种形象的典型OO行为是相同的,但只有重要属性/属性是常见的(非常重要的5-6个),其他属性如“兴趣等”(几乎10-15个属性)并不存在为botconfiguration文件

早先的编码人员为botconfiguration文件/用户configuration文件创build了独立的模型/控制器,这在每个地方都创build了很多的冗余,而且如预期的那样难以维护,编写testing等。我想干这个,至less解决一些/所有这些冗余问题。

有人build议Single Table Inheritance作为解决scheme

有人build议使用多态关联。

什么是更好的方法。 我们什么时候实际使用STI?

我自己的想法是,当模型的属性相同时,STI被最好地使用,并且它们在行为上有所不同。

关于我能做些什么的想法?

当属性相同但行为不同时,将STI表征为大多数情况下是有用的,但是可能有一些限制。 当我们喜欢使用STI的时候,顾名思义,就是清晰的OO风格的inheritance关系,而不是不同types的对象之间的数据库风格的关系。

如果机器人和用户之间有共同的代码,我会说STI听起来像是一个赢家。 如果只有一些共同的属性,可能不太适用,但仍值得一试。

我是一个很漂亮的实验人员,所以我的build议是放弃它。 分支你的代码并将模型重构成STI关系。 看看它是否确实干涸了事情,或只是换了一些头痛的其他问题。

有一件事我认为你不会看到太多的好处,就是干扰你的控制器。 根据我的经验,STI模型通常不会转化为类似的相关控制器。 但这是另一个可以尝试的东西。 有时候有胜利,有时候没有胜利。

我写了一篇关于这个话题的文章,包括与STI合作的一些技巧:

Rails中的单表inheritance

简而言之:在对象之间需要有一个明确的面向对象的inheritance关系(如womble雄辩的陈述),而不仅仅是一些共享的数据。 如果没有一个自然而明显的类层次结构,STIdevise可能会随着应用程序的发展而变得难以维持。

其次,你应该考虑把所有数据放在一张表中是否重要。 使用多态关联,您的数据库查询将变得更加复杂,并且可能会变慢。 如果您打算在网站上列出所有对象(例如,在一个表格中),那么STI可能就是要走的路。

第三,确保你的孩子class级没有太多独特的属性。 把所有的数据都放在一张表中,你不需要很多的非全局列。 这些不仅占用空间(不是主要问题),而且使数据结构混乱。 如果你确实有“特殊的”列,你应该在代码中明确地解释它们。

最后,如果您使用STI,我强烈build议您为所有的孩子模型使用一个控制器。 控制器的主要function是提供对象的访问,如果对象需要以不同的方式访问,那么STI可能不是正确的deviseselect。

看看我的文章(上面的链接)一些更有用的提示。

我可能会使用STI或根本没有特殊function。 你也许可以把所有的configuration文件都叫做configuration文件,如果它的用户是零,你就会知道它是否是一个“机器人”。 你也可以在不使用STI的情况下存储一个“type”字段。

某些事情会影响我使用STI的决定:

  • 是否有僵尸特定的逻辑
  • 有多less机器人与用户configuration文件(less量机器人意味着STI是好的 – 很多机器人,我可能会把它们存储在别的地方)

避免性传播感染的原因有时会阻碍你的发展。 例如,将一个对象从一种types转换为另一种types(在这种情况下是一个Bot到一个configuration文件)可能会相当麻烦。 有时一个简单的“types”字段更好。

值得注意的是,如果你使用STI,你可能需要一个通用的基类。 所以你可能需要ProfileBotProfileUserProfile 。 名字取决于你。 🙂

Rails STI的一个问题 – 大多数插件(等等)不完全支持。 你会发现自己修补了许多常见的东西。