2013-07-16 8 views
13

Ich versuche, ein Formular mit Daten in Sammlungsart abhängig von dem Benutzer zu erstellen, der protokolliert wird. Ich folge this chapter of the Symfony cookbook.Symfony form query_buider und entity repository

Alles funktioniert gut, wenn die query_builder Option eine Schließung ist, wo ich meine Daten von DQL bekomme. Da die Daten von einem anderen Speicherort im Code abgerufen werden müssen, würde ich die Abfrage lieber in der Repository-Klasse definieren. Hier

ist die Funktion in meinem Repository:

public function findOwnedBy($user) { 
    $query = $this->getEntityManager()->createQuery("SELECT l FROM MyBundle:Article a JOIN a.owndBy u WHERE u.id = :userId"); 
    $query->setParameters(array("userId"=>$user->getId())); 
    return $query->getResult(); 
} 

Diese Funktion arbeitet, wenn in einem Controller und ein Array von Artikel genannt. Hier ist ein Ausschnitt der symfony doc:

$formOptions = array(
        'class' => 'Acme\DemoBundle\Entity\User', 
        'multiple' => false, 
        'expanded' => false, 
        'property' => 'fullName', 
        'query_builder' => function(EntityRepository $er) use ($user) { 
         // build a custom query, or call a method on your repository (even better!) 
        }, 
       ); 

Wenn ich einen Aufruf an meine Repository-Funktion in den query_builder setzen, bekomme ich einen Fehler: Expected argument of type "Doctrine\ORM\QueryBuilder", "array" given, was ich verstehen kann, weil mein Repository einen Array von Entity zurückgibt, nicht ein QueryBuilder.

Ich möchte nicht Code duplizieren und einen neuen QueryBuilder im Formular erstellen. Was ist die beste Vorgehensweise, um die Abfrage aus dem Repository zu verwenden? Ich dachte daran, zwei Funktionen im Repository zu haben, von denen eines ein Array zurückgibt und das andere den QueryBuilder zurückgibt, aber der Kommentar in Symfony doc "oder rufen Sie eine Methode auf Ihrem Repository (noch besser!)" lassen Sie mich denken, es gibt einen besseren Weg für diesen Fall.

Antwort

24

Es sollte einfach sein. Sie haben folgende Möglichkeiten:

public function queryOwnedBy($user) { 

    $query = $this->createQueryBuilder('a') 
      ->from('MyBundle:Article', 'a') 
      ->innerJoin('a.owndBy', 'u') 
      ->where('u.id = :id')     
      ->setParameter('id', $user->getId()); 

    return $query; 
} 

public function findOwnedBy($user) { 
    return $this->queryOwnedBy($user) 
      ->getQuery() 
      ->getResult(); 
} 

dann in Form Builder:

$formOptions = array(
    'class' => 'Acme\DemoBundle\Entity\User', 
    'multiple' => false, 
    'expanded' => false, 
    'property' => 'fullName', 
    'query_builder' => function(EntityRepository $er) use ($user) { 
     return $er->queryOwnedBy($user); 
    }, 
); 

EDIT

Dankten für ncatnow und unagi ich die bisherigen Funktionen geändert haben Querybuilder

+0

Ich auch, obwohl es einfach sein sollte und das war mein erster Versuch. Dies gibt mir den Fehler 'Expected Argument vom Typ" Doctrine \ ORM \ QueryBuilder "," Array "angegeben. Es scheint, dass 'query_builder' ein QueryBuilder-Objekt erwartet, unabhängig davon, ob es direkt übergeben oder von einem Closure zurückgegeben wird. – Florent

+0

Bearbeitete die Post. Erstellen Sie zwei Funktionen, für die die Abfrage zurückgegeben wird, und eine weitere, die das Ergebnis zurückgibt. Rufen Sie auf dem Formulargenerator die Funktion auf, die die Abfrage zurückgibt. Das sollte funktionieren und ist immer noch DRY. Entschuldigung, ich werde die Namen ändern, da sie nicht passend sind. – saamorim

+0

hehe, es ist in der Tat, was ich getan habe und was ich im letzten Absatz der Frage beschreibe. Ich werde auf diese Weise gehen, der kleine Kommentar in Symfonys Doc lässt denken, dass es aus der Box funktionieren kann, es ist verwirrend;) – Florent

8
zurückzukehren

Ich habe nur eine kleine Reparatur von saamorim Antwort. Der Arbeitscode wäre so etwas wie:

public function queryOwnedBy($user) { 

    $query = $this->createQueryBuilder("u") 
      ->where('u.id = :id')     
      ->setParameter('id', $user->getId()); 

    return $query; 
} 

public function findOwnedBy($user) { 
    return $this->queryOwnedBy($user) 
      ->getQuery() 
      ->getResult(); 
} 
+0

Danke. Ich habe Ihre Antwort in meinen Beitrag integriert und die Abfrage so geändert, dass sie dem Beispiel entspricht. – saamorim

Verwandte Themen