Class 使用 Doctrine 设计多种配置文件类型
Class design for multiple profile types using Doctrine
这更像是设计问题的最佳实践。考虑到可能有多少种可能的答案,我将保持简短。
我正在使用 FOSUserBundle 为我正在构建的应用程序提供一些基本的用户管理。想象一下,我们在我的应用程序中有用户,并且用户可以拥有与他们关联的 2 种类型的配置文件中的一种 (1:1)。
设置它的最佳做法是什么?即用户对象包含所有用户的公共字段(如名字、姓氏、电子邮件等),但其他配置文件中将包含不同的字段。
User
Profile Type A
Profile Type B
我知道我需要额外的 classes 以及它们之间的某种关系,所以我应该...
- 使用 Doctrine 中的 1:1 映射功能(类似于 Symfony 类别和产品书中的示例)?
- 完全放弃
Profile A/B
class 并使用继承,以便我的 A 和 B 类型继承和扩展 User
class?例如PrimaryUser
、SomeOtherUser
- None以上,你有更好的想法或者一些post我搜索没有找到。 :)
非常感谢。我已经有一段时间没有做 OO 设计了(虽然错过了!),我对这类事情有点生疏。
在类似的情况下(一个用户有多个可能的配置文件处于活动状态)我们用从用户到角色的 one2many 对这种情况进行建模,角色 table 是一个 doctrine2 映射超类,具有单个 Table 继承 (see this doc).
描述情况的一些示例代码:
用户原则Class:
<?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;
.....
角色原则Class:
<?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();
}
.....
角色描述原则Class
<?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;
.....
希望对您有所帮助
这更像是设计问题的最佳实践。考虑到可能有多少种可能的答案,我将保持简短。
我正在使用 FOSUserBundle 为我正在构建的应用程序提供一些基本的用户管理。想象一下,我们在我的应用程序中有用户,并且用户可以拥有与他们关联的 2 种类型的配置文件中的一种 (1:1)。
设置它的最佳做法是什么?即用户对象包含所有用户的公共字段(如名字、姓氏、电子邮件等),但其他配置文件中将包含不同的字段。
User
Profile Type A
Profile Type B
我知道我需要额外的 classes 以及它们之间的某种关系,所以我应该...
- 使用 Doctrine 中的 1:1 映射功能(类似于 Symfony 类别和产品书中的示例)?
- 完全放弃
Profile A/B
class 并使用继承,以便我的 A 和 B 类型继承和扩展User
class?例如PrimaryUser
、SomeOtherUser
- None以上,你有更好的想法或者一些post我搜索没有找到。 :)
非常感谢。我已经有一段时间没有做 OO 设计了(虽然错过了!),我对这类事情有点生疏。
在类似的情况下(一个用户有多个可能的配置文件处于活动状态)我们用从用户到角色的 one2many 对这种情况进行建模,角色 table 是一个 doctrine2 映射超类,具有单个 Table 继承 (see this doc).
描述情况的一些示例代码:
用户原则Class:
<?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;
.....
角色原则Class:
<?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();
}
.....
角色描述原则Class
<?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;
.....
希望对您有所帮助