Symfony / Doctrine - 多个用户类型

3
我正在创建一个网站,应该有至少两种类型的用户,公司和客户,它们都有相同的登录表单和不同的注册表单,并且他们可以互发消息...
通常情况下(不考虑Doctrine),我认为数据库应该长这样:
User(id,email,password,facebook_id,roles)
Company(id,user_id,name,city,...)
Client(id,user_id,name,sex ...)
Messages(id,sender_id(user_id),receiver_id(user_id),message,...)
...
现在我想知道使用DoctrineSymfony 4实现这些要求的最佳和最简单的方法是什么?实体应该长什么样子?
(注意:我没有使用FOSUserBundle

2
Doctrine文档包含一个关于管理不同类型继承的部分,这应该能帮助您入门。如果您遇到任何具体问题,请随时提出具体问题,但我担心现在这个问题太广泛了,无法有意义地回答。 - dbrumann
是的,我找到了Doctrine文档中的“继承映射”部分,希望我能理解其中的内容,因为我是Symfony/Doctrine世界的新手。 - Az.Youness
2
没问题,试试运气吧,如果遇到任何问题,请随时在这里寻求帮助。回答带有现有代码片段和错误消息的问题总是比回答开放性问题更容易。这只意味着需要做很多工作,最坏的情况是即使对你来说也不如文档和稍微尝试一下有用。 :) - dbrumann
1个回答

6

实现这个领域:

  • 用户
  • 公司
  • 客户端

你可以考虑两种不同的方法:

第一种方法

这种方法使用关联。如果选择此方法,您应根据某些逻辑手动将适当的公司或客户端链接到当前用户。每个用户在任何给定时间点上可能只有其中一个字段。公司或客户端,而不是两者都有。

用户

/** @Entity */
class User
{
    /**
     * @ORM\column(type="string")
     */
    protected password;

    /**
     * @ORM\column(type="array")
     */ 
    protected roles;

    /**
     * @ORM\OneToOne(targetEntity="Company", mappedBy="user")
     */
    protected Company;

    /**
     * @ORM\OneToOne(targetEntity="Client", mappedBy="user")
     */ 
    protected Client;
}

公司

/** @Entity */
class Company
{
    /**
     * @ORM\column(type="string")
     */
    protected city;

    /**
     * @ORM\OneToOne(targetEntity="User", inversedBy="company")
     */ 
    protected user;
}

客户端

/** @Entity */
class Client
{
    /**
     * @ORM\column(type="string")
     */
    protected sex;

    /**
     * @ORM\OneToOne(targetEntity="User", inversedBy="client")
     */ 
    protected user;
}

第二种方法

这种方法使用继承,似乎更加灵活,但也有自己的缺点。

用户

/** @MappedSuperclass */
class User
{
    /**
     * @ORM\column(type="string")
     */
    protected password;

    /**
     * @ORM\column(type="array")
     */ 
    protected roles;
}

公司

/** @Entity */
class Company extends User
{
    /**
     * @Id @Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\column(type="string")
     */
    protected city;
}

客户端

/** @Entity */
class Client extends User
{
    /**
     * @Id @Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\column(type="string")
     */
    protected sex;
}

您还有一个一对多的关系,涉及到用户消息:

  • 一个 用户可以拥有多个 消息
  • 一条 消息只属于一个 用户

使用上面的第一种方法很好,但使用第二种方法,您会遇到麻烦,因为Doctrine说:

由映射的超类定义的持久性关系必须是单向的(只有一个拥有方)。这意味着在映射的超类上不可能使用一对多的关联。


谢谢,我选择了第一种方法(组合),看起来这是实现我的要求的最佳方式,我发现使用继承方法的另一个问题是例如在我的应用程序中的某些步骤中(注册应该分为两个步骤..)我需要更新/更改用户鉴别器列,并且使用Doctrine继承无法/不好的做到这一点..该问题在这里有所描述。 - Az.Youness
现在可以了。关于Symfony,如有任何其他问题,请随时提问。如果有帮助,请接受并点赞。 - Peyman Mohamadpour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接