2011-02-10 25 views
11

Mam zamiar użyć entity_manager w moim modelu. Ale entity_manager jest dostępny tylko w kontrolerze: throw $em = $this->get('doctrine.orm.entity_manager'). Tak więc, muszę zdefiniować metody modelowe z parametrem $em. To sprawia, że ​​testowanie phpUnit jest bardzo trudne i narusza strukturę aplikacji. Na przykład:Jednostka podmiotu Symfony2 w modelu

class Settings 
{ 
    public static function getParam($em, $key) 
    { 
     $em->createQuery(" 
      SELECT s 
      FROM FrontendBundle:Settings s 
      WHERE s.param = {$key} 
     "); 
     return $em->getResult(); 
    } 
} 

Czy istnieje podejście do korzystania z usługi entity_manager w sekcji model?

Odpowiedz

8

Zapytania w klasie Entity

Umieszczanie zapytań w was podmiotu wydaje się dziwne dla mnie. Tak samo jak umieszczanie zapytań w klasie twojego modelu w Doctrine 1, nie jest to uważane za dobrą praktykę. Klasy jednostek powinny być lekkie.

Właściwie uczę się Doctrine2 i myślałem o podobnym problemie: gdzie umieścić zapytania?

W Naukach 1 istnieją specjalne zajęcia stołowe i spodziewałem się czegoś podobnego w Naukach 2.

Repository Wzór

Dziś dowiedziałem się, że Doctrine 2 korzysta z repozytorium Wzór: http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html#custom-repositories

Jednak aby pobrać instancję klasy repozytorium, należy użyć Entity Manager. Tak czy inaczej potrzebujesz.

Nadal, podążanie za wzorem repozytorium wydaje się lepszym wyborem.

Moim zdaniem Jeśli nalegasz na posiadanie metody zapytania w swojej klasie Entity, musisz przekazać mu Entity Manager.

Testowanie

Dlaczego potrzeba przekazywania kierownika jednostki sprawia, że ​​trudno przetestować? Z mojego doświadczenia wynika, że ​​wyraźne zależności sprawiają, że testowanie jest łatwiejsze, ponieważ można je kontrolować w teście (i na przykład kpić z nich).

Z drugiej strony przekazanie podmiotu zarządzającego podmiotem do każdej metody nie jest właściwym wyborem. W takim przypadku uzależniam zależność i dodaję ją do contructora.

14

Po pierwsze, informacja początkowa: zgodnie z konwencją klasa jednostek powinna być prawdopodobnie liczbą pojedynczą. A więc ustawienie, a nie ustawienia. Można argumentować, że "ustawienia" jako grupa powiązanych ustawień mogą być postrzegane jako jedna całość. Wciąż jednak coś na uwadze.

W Doctrine2 użyłbyś repozytorium do utworzenia tego typu zapytania. W kodzie, w którym chcesz zadzwonić pod numer Settings::getParam, zamiast tego pobierzesz repozytorium i zapytasz o to. W Symfony2, powiedzieć:

// $em is your entitymanager, as you were going to pass to your method above 
// $key is the key you were going to pass to your method above 
$repository = $em->getRepository('\FrontendBundle\Settings'); 
$setting = $repository->getByParam($key); 

Domyślnie, bez konieczności pisania kodu, repozytoria określić getByXXXX dla każdego pola w swojej jednostce.

Jeśli masz bardziej skomplikowane zapytanie, możesz rozszerzyć repozytorium.

use Doctrine\ORM\EntityRepository; 

class SettingsRepository extends EntityRepository 
{ 
    public function getBySomeComplicatedQuery() { 
     $sort_order = $this->getEntityManager() 
      ->createQuery('SELECT count(s) FROM FrontendBundle\Settings s WHERE s.value > 32') 
      ->getResult(Query::HYDRATE_SINGLE_SCALAR); 
    } 

} 

A potem nazwałbyś tę metodę w ten sam sposób.

Inni byliby zwolennikami użycia obiektu Manager, który nie byłby wtedy związany z Entity/ORM, ale jest to niepotrzebne komplikowanie w tym przypadku.

Doctrine2 został zaprojektowany tak, aby nie pozwalał używać zapytań w pliku Entity; Jednostki i EntityManagers to w rzeczywistości dwa aspekty standardowej warstwy modelu, podzielone w celu wymuszenia najlepszych praktyk. Zobacz ten artykuł: http://symfony2basics.jkw.co.nz/get-symfony2-working/entities/

+0

Witam, ostatni link zniknął. – userfuser