两个不同的子类扩展同一个实体实例

时间:2016-05-18 17:54:47

标签: php inheritance orm doctrine-orm

我正在开发一个管理法庭口译服务的应用程序(使用Doctrine和Zend Framework 2)。有很多人参与其中有各种专业角色,因此是Person超类和子类。类层次结构在垂直意义上并不复杂 - 一代继承就足够了 - 但横向方面给我带来了麻烦。

我认为mapped superclasses不适合我的情况。我也考虑过single-table inheritance,但这会很快变得丑陋,因为子类有自己的实体关系,太多的东西可以优雅地塞进一个表中。

这给我们留下了class table inheritance,这在很多方面都非常合适,但是......我会有很多情况下子类User(用于身份验证)和子类Interpreter将(或应该)指向父数据表中的同一行,因为它们代表现实中的同一个人。但是由于鉴别器列你必须选择其中一个,或者创建两个不同的行来保存相同的数据 - 并且规范化警察应该为你提供。

我认为User或Interpreter实体可能只需与Person实体建立一对一的关系,并半手动处理。我认为另一个选择是将User折叠为Person - 但这很难看,因为很多人不会进行身份验证,也不会拥有或需要密码。 我看过了 Doctrine inheritance, several entities extending the same super classHow to change and entity type in Doctrine2 CTI Inheritance(除其他外)并且没有人解决这个问题。

所以,我想知道是否有人有任何建议。感谢。

2 个答案:

答案 0 :(得分:2)

听起来你正在管理一堆关于Person的数据,这些数据可以识别世界上的个人。由于系统中只有部分人员是Users,因此我认为对身份验证,审计日志记录,通知等的担忧与Person类层次结构的问题是分开的。< / p>

我建议从User类层次结构中删除Person。也许将其重命名为Account,以使其感觉更少人格。 Account可以具有owner属性,该属性与Person有关。如果您想使用Person的电子邮件地址作为身份验证的标识符,那很好。如果您以后想要添加username,那将是Account的属性,因为它只在该上下文中有意义。

答案 1 :(得分:1)

不确定底层代码(不是ZF开发人员),但我认为您混淆了行为和数据。

要使身份验证正常工作,您确实不需要继承。刚刚找到了代码接口依赖的代码。

要使用户能够进行身份验证(而通用人员不能) - 使用继承,或者如@timdev建议的那样使用关系。在symfony世界中,我最好写一些像

这样的东西
class User extends Person implement UserInterface {
  //... implementation
}

class Person {
  //...
}

之后你可以确定,你有UserInterface的任何服务和身份验证。

如果您必须动态切换User实体的基础类(即您有Author extends Person并希望允许某些作者登录),我认为合成是唯一合适的解决方案。拆分逻辑,拆分entites,拆分数据。快乐。