2012-04-26 22 views
5

Jestem nowicjuszem w Doctrine, mongo i ustawieniu ODM i podczas grania z tą konfiguracją w ZF1 Próbuję replikować prostą do wielu referencję z przymus. Oto sytuacja i chciałbym, aby niektórzy doradzili, jak to osiągnąć.Doctrine ODM MongoDB - Replikacja prostego Jeden do wielu odniesień z ograniczeniami

jest to proste dla użytkownika> mapowanie rolę, tak w sytuacji, sql musiałbym tabele następująco:

 
Users 
- id 
- name 
- role_id 

Roles 
- id 
- name 

Wtedy ograniczenie klucza obcego będzie ustawiony na użytkowników ROLE_ID mapować do roli ID. I po usunięciu roli zostanie wywołane ograniczenie klucza obcego, zatrzymujące operację.

Jak osiągnąć ten sam cel w Docrines MongoDB ODM?

Do tej pory grałem z różnymi rodzajami adnotacji na jednostki użytkownika w tym @ReferenceOne @ReferenceMany z różnymi opcjami kaskadowych ...

Wybór opuścił mnie teraz jest wdrożenie @PreUpdate, @PreRemove wydarzenia w cyklu życia w encji "rola", a następnie sprawdź, czy żaden użytkownik nie używa tej roli, jeśli są one w trakcie aktualizacji, zmień odniesienie do dopasowania lub przy usuwaniu, wyślij wyjątek.

Czy jestem tutaj, czy zgubiłem?

Dziękuję

Si

Odpowiedz

7

na coś takiego bym nie dwie oddzielne tabele „” jak byś w SQL. Po prostu masz typ roli jako własność użytkownika. A jeśli chcesz usunąć typ roli, możesz po prostu manipulować polem ról wszystkich użytkowników z tą rolą.

Ale żeby odpowiedzieć na twoje pytanie, zrobiłbym to tak.

<?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(); 
    } 
} 

Następnie utworzyłbym klasę usług do pracy z moim menedżerem dokumentów.

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(); 
     } 
    } 
} 
+0

Świetna odpowiedź, dziękuję bardzo! –

+1

Bez problemu. Przeszedłem ten sam ból, co ty, gdy zaczynałeś z Doctrine. To niesamowite, gdy już to zrozumiesz! –

+1

Myślę, że jest to naprawdę dobre. To sprawia, że ​​tworzenie warstwy usługi nad wierzchołkiem jest znacznie łatwiejsze. Jeden mały punkt to I Role :: hasUsers() powinien powrócić! $ This-> users-> isEmpty(); odwrócić wartość logiczną. Bardzo dziękuję za pomoc, a to działa jak marzenie. –