2015-06-29 10 views
6

Korzystanie z Symfony 2.7 i doktryny 2.5, mamGet repozytorium jednostką docelową z klasy abstrakcyjne w doktrynie 2,5

  • Interface Alsciende\MyBundle\Model\CycleInterface
  • klasą abstrakcyjną Alsciende\MyBundle\Entity\Cycle który implementuje interfejs
  • końcowa klasa AppBundle\Entity\Cycle, która rozszerza klasę abstrakcyjną i implementuje interfejs
  • konfigurację doktryny z resolve_target_entities, która mapuje interfejs do ostatniej klasy

Ten system działa dobrze i udało mi się stworzyć bazę danych i wprowadzić trochę CRUD w AppBundle, bezpośrednio manipulując obiektem docelowym.

Jednak teraz chcę manipulować obiektem docelowym w MyBundle, poprzez interfejs. Muszę jej repozytorium:

$this->getDoctrine()->getRepository('Alsciende\MyBundle\Model\CycleInterface'); 

Ale pojawia się wyjątek

class 'Alsciende\MyBundle\Model\CycleInterface' does not exist 

Jak mogę uzyskać repozytorium jednostki docelowej? To znaczy, w jaki sposób można wywołać bezpośrednio ResolveTargetEntityListener, aby uzyskać nazwę podmiotu implementującego interfejs?

edit:

Dlaczego muszę to? Bardzo prosto, na przykład, potrzebuję kontrolera, który wyświetla listę wszystkich Cykli. Interfejs określa, że ​​każdy cykl ma identyfikator i nazwę. Chcę wyświetlić każdy cykl z jego nazwą i identyfikatorem. W tym celu muszę uzyskać dostęp do repozytorium rzeczywistych jednostek Cycle.

Alsciende/MyBundle/Model/CycleInterface.php

<?php 

namespace Alsciende\MyBundle\Model; 

interface CycleInterface 
{ 
    public function getId(); 
    public function getName(); 
} 

Alsciende/MyBundle/Controller/CycleController.php

<?php 

namespace Alsciende\MyBundle\Controller; 

class CycleController extends Controller 
{ 
    public function indexAction() 
    { 
     $cycles = $this 
      ->getDoctrine() 
      ->getRepository('Alsciende\MyBundle\Model\CycleInterface') 
      ->findAll(); 

     // return template with list $cycles 
     // using only id and name properties 
    } 
} 

To ten sam sposób, że FosUserBundle jest w stanie zarządzać Podmioty użytkownika, mimo że klasa Użytkownika zdefiniowana w FosUserBundle jest klasą abstrakcyjną.

+1

Czy czytałeś o Dziedziczeniu doktryny? http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html –

+0

Zrobiłem. Zastosowałem to, co jest w tej dokumentacji. – Alsciende

+0

Czytałem, na innym pytaniu SO, że możesz tylko zapytać 'Doctrine' o coś, co może być utworzone ... Oczywiście, ani' interface' ani 'abstract class' nie mogą być. Może ktoś inny mógłby rozwinąć ten ... –

Odpowiedz

-1

Jak mogę uzyskać repozytorium jednostki docelowej?

W app/config/config.yml put:

doctrine: orm: resolve_target_entities: Namespace\InterfaceInterface: Namespace\Entity\TargetEntityImplementing

ALE

Dlaczego muszę to? Bardzo prosto, na przykład, potrzebuję kontrolera, który wyświetla listę wszystkich Cykli. Interfejs określa, że ​​każdy cykl ma identyfikator i nazwę. Chcę wyświetlić każdy cykl z jego nazwą i identyfikatorem. W tym celu muszę uzyskać dostęp do repozytorium rzeczywistych jednostek Cycle.

To nie jest rozwiązanie w tym przypadku, IMO. Wolałbym użyć podmiotu z @DiscriminatorColumn skonfigurowanego: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html#single-table-inheritance

Klasa nadrzędna będzie pewnego rodzaju interfejsem, którego szukasz.

Polecam "scalić" powyżej: utwórz klasę nadrzędną, która będzie implementować taki interfejs, a następnie zamapuj ten interfejs na tę klasę.

+0

Dziękuję za odpowiedź. @DiscriminatorColumn nie jest dobrym rozwiązaniem w moim przypadku. Mam tylko jedną ostatnią klasę implementującą CycleInterface. Ale próbuję manipulować tą ostatnią klasą, nie wiedząc o tym jeszcze, poprzez jej interfejs, jak to, co robi FOSUserBundle z UserInterface. – Alsciende

+0

Nie można opisać interfejsu. Musi to być klasa natychmiastowa lub - jeśli jest to zmapowana superklasa - abstrakt, która jest rozszerzona o jednostkę docelową. – eRIZ

+0

Moje pytanie sprowadza się do czegoś bardzo prostego: "w jaki sposób mogę bezpośrednio użyć narzędzia ResolveTargetEntityListener?". Twoja odpowiedź nie wydaje się być naprawdę powiązana. Albo można bezpośrednio wywołać ResolveTargetEntityListener, albo nie. – Alsciende