我是Doctrine,mongo和ODM设置的新手,在ZF1中使用此设置时,我试图用约束复制一个简单的一个到多个引用。以下是这种情况,并希望就如何实现这一目标提出一些建议。
这是一个简单的用户 - >角色映射,因此在sql情况下我会有如下表:
Users - id - name - role_id Roles - id - name
然后,将在用户role_id上设置外键约束以映射到角色ID。删除角色后,将触发外键约束,停止操作。
如何在Doctrines MongoDB ODM中实现相同的目标?
到目前为止,我已经在User实体上使用了不同类型的注释,包括带有不同级联选项的@ReferenceOne @ReferenceMany ......
现在留给我的选择是在'角色'实体上实现@PreUpdate,@ PreRemove生命周期事件,然后检查没有用户正在使用该角色,如果他们正在更新,则更改引用以匹配或删除抛出异常。
我在这里还是输了?
谢谢,
的Si
答案 0 :(得分:7)
对于类似的东西,我不会像在SQL中那样有两个单独的'表'。您只需将角色类型作为用户的属性即可。然后,如果您想要删除角色类型,您只需操纵具有该角色的所有用户的角色字段。
但要回答你的问题,我会这样做。
<?php
class User {
/** @MongoDB\Id */
protected $id;
/** @MongoDB\String */
protected $name;
/** @MongoDB\ReferenceOne(targetDocument="Role", mappedBy="user") */
protected $role;
//Getters/Setters
}
class Role {
/** @MongoDB\Id */
protected $id;
/** @MongoDB\String */
protected $name;
/** @MongoDB\ReferenceMany(targetDocument="User", inversedBy="role") */
protected $users;
public function _construct() {
$this->users = new Doctrine\Common\Collections\ArrayCollection;
}
// Getters/Setters
public function hasUsers() {
return !$this->users->isEmpty();
}
}
然后我会创建一个服务类来处理我的文档管理器。
class RoleService {
public function deleteRole(Role $role) {
if (!$role->hasUsers()) {
// Setup the documentManager either in a base class or the init method. Or if your über fancy and have php 5.4, a trait.
$this->documentManager->remove($role);
// I wouldn't always do this in the service classes as you can't chain
// calls without a performance hit.
$this->documentManager->flush();
}
}
}