如何将关联限制为 Doctrine 中另一个关联的子集?
How to restrict associations to a subset of another association in Doctrine?
我对 Doctrine 中同一对象的多个映射有点困惑。该应用程序基于 Symfony 顺便说一句,因此注释略有不同。
基本上我有以下对象:
- 组织:一把保护组织属性的伞
- 部门:组织内的一个部门
- 用户:通用用户对象
这些对象的关联如下:
- 一个组织总是只有一个所有者,即
User
- 一个组织有很多成员,都是
User
的
- 一个部门由许多
User
组成,但只允许 Organisation
和 Department
的成员
我有点卡在第三个要求...首先,这是我的对象或多或少看起来像 atm 的方式:
/**
* @ORM\Entity
* @ORM\Table(name="organisations")
*/
class Organisation
{
// ...
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="organisation")
*/
private $owner;
/**
* ORM\OneToMany(targetEntity="User", mappedBy="organisation")
*/
private $members
}
/**
* @ORM\Entity
* @ORM\Table(name="departments")
*/
class Department
{
// ...
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="departments")
*/
private $members
/**
* @ORM\ManyToOne(targetEntity="Organisation", inversedBy="departments")
*/
private $organisation;
}
/**
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User
{
// ...
/**
* The organisation this user "owns"
*
* @ORM\OneToOne(targetEntity="Organisation", mappedBy="owner", nullable=true)
*/
private $owning_organisation;
/**
* @ORM\ManyToOne(targetEntity="Organisation", inversedBy="members")
*/
private $organisations;
/**
* @ORM\ManyToMany(targetEntity="Department", inversedBy="members")
* @ORM\JoinTable(name="users_departments")
*/
private $departments;
}
现在这基本上可以工作了,如果且仅在控制器中我进行了所有检查(类似于 (if( $user->isPartOfOrganisation($department-getOrganisation()) { $department->addMember($user); }
)。
但是有没有办法在设计层面上限制可能的对象关联?所以基本上我想要的是,如果一个用户被添加到一个部门,那么只有当该用户已经是该部门所属的组织的一部分时,才有可能。或者我应该在 Department
对象的 addMember()
方法中进行检查吗?我可以想象(但找不到)存在某种子集限制(Department::members is subset of Organisation::members
)。
为了尽可能在低级别(最接近数据库)实施此检查,我认为唯一的解决方案是 Doctrine Event Listener that in the pre-persist event check for your custom constraint. Read more about Doctrine Event System .
顺便说一句,我认为你可以用更简单的方式来处理这种情况:我建议你将 业务逻辑封装到一个服务中 (这样你就可以更简单地重用它)并且在您将在管理这种情况的表单中使用的 自定义验证器 中使用它。
如果您需要更多技巧来开发其中一种解决方案,或者您发现了更有用的东西,请告诉我。
希望对您有所帮助
我对 Doctrine 中同一对象的多个映射有点困惑。该应用程序基于 Symfony 顺便说一句,因此注释略有不同。
基本上我有以下对象:
- 组织:一把保护组织属性的伞
- 部门:组织内的一个部门
- 用户:通用用户对象
这些对象的关联如下:
- 一个组织总是只有一个所有者,即
User
- 一个组织有很多成员,都是
User
的 - 一个部门由许多
User
组成,但只允许Organisation
和Department
的成员
我有点卡在第三个要求...首先,这是我的对象或多或少看起来像 atm 的方式:
/**
* @ORM\Entity
* @ORM\Table(name="organisations")
*/
class Organisation
{
// ...
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="organisation")
*/
private $owner;
/**
* ORM\OneToMany(targetEntity="User", mappedBy="organisation")
*/
private $members
}
/**
* @ORM\Entity
* @ORM\Table(name="departments")
*/
class Department
{
// ...
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="departments")
*/
private $members
/**
* @ORM\ManyToOne(targetEntity="Organisation", inversedBy="departments")
*/
private $organisation;
}
/**
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User
{
// ...
/**
* The organisation this user "owns"
*
* @ORM\OneToOne(targetEntity="Organisation", mappedBy="owner", nullable=true)
*/
private $owning_organisation;
/**
* @ORM\ManyToOne(targetEntity="Organisation", inversedBy="members")
*/
private $organisations;
/**
* @ORM\ManyToMany(targetEntity="Department", inversedBy="members")
* @ORM\JoinTable(name="users_departments")
*/
private $departments;
}
现在这基本上可以工作了,如果且仅在控制器中我进行了所有检查(类似于 (if( $user->isPartOfOrganisation($department-getOrganisation()) { $department->addMember($user); }
)。
但是有没有办法在设计层面上限制可能的对象关联?所以基本上我想要的是,如果一个用户被添加到一个部门,那么只有当该用户已经是该部门所属的组织的一部分时,才有可能。或者我应该在 Department
对象的 addMember()
方法中进行检查吗?我可以想象(但找不到)存在某种子集限制(Department::members is subset of Organisation::members
)。
为了尽可能在低级别(最接近数据库)实施此检查,我认为唯一的解决方案是 Doctrine Event Listener that in the pre-persist event check for your custom constraint. Read more about Doctrine Event System .
顺便说一句,我认为你可以用更简单的方式来处理这种情况:我建议你将 业务逻辑封装到一个服务中 (这样你就可以更简单地重用它)并且在您将在管理这种情况的表单中使用的 自定义验证器 中使用它。
如果您需要更多技巧来开发其中一种解决方案,或者您发现了更有用的东西,请告诉我。
希望对您有所帮助