5

I'm new to Doctrine, mongo and the ODM setup and while playing with this setup in ZF1 I'm trying to replicate a simple one to many reference with a constraint. Here is the situation and would like some advise on how to achieve this.

This is a simple user->role mapping, so in a sql situation I would have tables as follows:

Users
 - id
 - name
 - role_id

Roles
 - id
 - name

Then a foreign key constraint would be set on the users role_id to map to the role id. And upon deleting a role a foreign key constraint would be triggered stopping the operation.

How could I achieve the same goal in Doctrines MongoDB ODM?

So far I have played with different types of annotations on the User entity including @ReferenceOne @ReferenceMany with different cascade options...

The choice left to me now is to implement @PreUpdate, @PreRemove lifecycle events on the 'role' entity and then check that no users are using the role, if they are then on update change the reference to match or on remove throw an exception.

Am I right here or lost ?

Thank you,

Si

4

1 に答える 1

7

そのような場合、SQL のように 2 つの別個の「テーブル」はありません。ユーザーのプロパティとしてロールタイプを持っているだけです。次に、役割タイプを削除したい場合は、その役割を持つすべてのユーザーの役割フィールドを操作するだけです。

しかし、あなたの質問に答えるために、私はそうします。

<?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();
        }
    }
}
于 2012-04-26T22:56:23.020 に答える