使用Doctrine的多个配置文件类型的类设计

时间:2015-01-26 01:52:50

标签: php symfony doctrine-orm doctrine

这是设计问题中的最佳实践。考虑到可能有多少可能的答案,我会简单而简单。

我正在使用FOSUserBundle为我正在构建的应用程序提供一些基本的用户管理。想象一下,我的应用程序中有用户,用户可以拥有与其关联的两种类型的配置文件中的一种(1:1)。

设置它的最佳做法是什么?即用户对象包含所有用户的公共字段(诸如名字,姓氏,电子邮件等),但其他配置文件中将包含不同的字段。

User Profile Type A Profile Type B

我知道我需要额外的课程和他们之间的某种关系,所以我应该......

  • 在Doctrine中使用1:1映射功能(类似于Symfony类别和产品中的示例)?
  • 完全使用Profile A/B类进行分配并使用继承,以便我的A和B类型继承并扩展User类?例如PrimaryUserSomeOtherUser
  • 以上都没有,你有更好的想法或一些我找不到的帖子。 :)

非常感谢你。我做了OO设计已经有一段时间了(虽然错过了!)而且我对这类事情有点生气。

1 个答案:

答案 0 :(得分:3)

在类似的情况下(一个用户有多个可能的配置文件处于活动状态),我们使用one2many从用户到角色建模情况,角色表是 doctrine2具有单表继承的映射超类({{ 3}})。

用于描述情况的一些示例代码:

用户主义类:

<?php
namespace Acme\SecurityBundle\Entity;

/**
 *
 * @ORM\Table(name="acme_user")
 * @ORM\Entity()
 */
class AcmeUser implements AdvancedUserInterface
{

    /**
     * One-To-Many
     *
     * @ORM\OneToMany(targetEntity="Acme\SecurityBundle\Entity\AcmeUserRoles", mappedBy="acmeUser",cascade={"persist"})
     */
    protected $acmeRoles;
    .....

角色主义课程:

<?php
namespace Acme\SecurityBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Role\RoleInterface;

/**
 * @ORM\Entity
 * @ORM\Table(name="acme_user_roles")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"customerRole" = "ACmeCustomerRole", "user" = "AcmeUserRoles","driver" = "AcmeDriverRole"})
 */
class AcmeUserRoles implements RoleInterface
{


    /**
     * Bidirectional
     *
     * @ORM\ManyToOne(targetEntity="Acme\SecurityBundle\Entity\AcmeUser", inversedBy="acmeRoles",cascade={"persist"})
     * @ORM\JoinColumn(name="acme_user_id", referencedColumnName="id", onDelete="cascade")
     */
    protected $acmeUser;


    /**
     * Bidirectional
     *
     * @ORM\ManyToOne(targetEntity="Acme\SecurityBundle\Entity\AcmeRole", inversedBy="acmeUserRoles",cascade={"persist"})
     * @ORM\JoinColumn(name="acme_role_id", referencedColumnName="id", onDelete="cascade")
     */
    protected $acmeRole;

    /**
     * Implementation of getRole for the RoleInterface.
     *
     * @return string The role.
     */
    public function getRole()
    {
        return $this->getAcmeRole()->getName();
    }
    .....

角色描述教义类

<?php
namespace Acme\SecurityBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Entity
 * @ORM\Table(name="acme_role")
 **/
class AcmeRole
{
    const USER_ROLE_NAME = "ROLE_ACME_USER";
    const DRIVER_ROLE_NAME = "ROLE_ACME_DRIVER";
    ....

    /**
     * @ORM\ManyToMany(targetEntity="AcmeModule", inversedBy="rolePermissionsTemplate")
     * @ORM\JoinTable(name="acme_role_permission_template",
     *  joinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id", onDelete="cascade")},
     *  inverseJoinColumns={@ORM\JoinColumn(name="module_id", referencedColumnName="id", onDelete="cascade")}
     * )
     */
    protected $permissionsTemplate;

    /**
     * One-To-Many
     *
     * @ORM\OneToMany(targetEntity="Acme\SecurityBundle\Entity\AcmeUserRoles", mappedBy="acmeRole",cascade={"persist"})
     */
    protected $acmeUserRoles;
    .....

希望这个帮助