2016-07-23 4 views
2

Ich bin sehr neu in Symfony, komme aus einem Kohana-Hintergrund und habe eine harte Zeit, mich an Doctrine zu gewöhnen.Übergeht createQueryBuilder von Doctrine die Getter-Methoden von Entities?

Zur Zeit habe ich eine Produkttabelle, die ich innerlich einige andere Tabellen mit dem createQueryBuilder verbinden und einige zusätzliche Logik in der Getter-Methode für die Produkt-Entität hinzufügen muss. Es scheint jedoch, dass die Getter-Methoden nicht einmal verwendet werden. Hier einige Auszüge aus meinen Code:

//From AppBundle\Controller\ProductController 

$repository = $this->getDoctrine()->getRepository('AppBundle:Product'); 
$products = $repository->findWithLimitNew(24); 

//From AppBundle\Repositories\ProductRepository 
public function findWithLimitNew($limit=1) 
{ 
    $em = $this->getEntityManager(); 
    $qb = $em->createQueryBuilder(); 
    $qb->select('p.name', 'p.id', 'p.slug', 'pc.name AS catname') 
     ->from('AppBundle\Entity\Product', 'p') 
     ->innerJoin(
      'AppBundle\Entity\ProductAttributes', 
      'pa', 
      \Doctrine\ORM\Query\Expr\Join::WITH, 
      'p.id = pa.productId' 
     ) 
     ->innerJoin(
      'AppBundle\Entity\ProductCategories', 
      'pc', 
      \Doctrine\ORM\Query\Expr\Join::WITH, 
      'pa.value = pc.id' 
     ) 
     ->where('pa.type = 1') 
     ->where('pa.default = 1') 
     ->setMaxResults($limit); 

    return $qb->getQuery()->getResult(); 
} 

// From AppBundle\Entity\Product 
/** 
* Get name 
* 
* @return string 
*/ 
public function getName() 
{ 
    #return $this->name; //<--Commenting this out for now 
    return 'Some stupid string'; 
} 

// From index.twig.html 
{% for product in products %} 
<h1>{{product.name}}</h1> 
{% endfor %} 

Nun, wie Sie sehen, kann ich die Getter-Methode getName() haben einen String zurückkehrt, aber wenn die Ansicht gerendert wird ich den Produktnamen, nicht die Zeichenfolge ich bin Rückkehr. Was gibt?

+1

Wie Sie vermuteten, verwendet Doctrine 2 beim Hydratisieren einer Entität (d. H. Beim Abrufen aus der Datenbank) Reflektion, um die Entitätseigenschaften direkt festzulegen. Alle Methoden (einschließlich des Konstruktors) werden ignoriert. Und DQL ist nicht SQL. Ich bin überrascht, dass Ihre Anfrage überhaupt etwas zurückgibt. – Cerad

+0

@Cerad Meine Abfrage kommt von einer Doctrine-Website und die Abfrage funktioniert einwandfrei. Natürlich habe ich meine Tabellennamen geändert. – pogeybait

+0

Ist Ihr "Name" -Feld in AppBundle \ Entity \ Product als öffentlich markiert? Wenn das der Fall ist, könnte es daran liegen, dass Zweig sieht, dass die Eigenschaft öffentlich ist und sich nicht damit beschäftigt, den Getter aufzurufen. Versuchen Sie es privat zu machen und lassen Sie den Getter als öffentlich – valepu

Antwort

0

@Cerad hat einen Punkt. Auf den ersten Blick sieht Ihre Abfrage aus wie DQL nicht QB. Aber jetzt habe ich erkannt Code korrekt ist, können Sie Ihre Querybuilder (QB) Code einiges vereinfachen:

$qb->select('p') 
    ->from('AppBundle:Product', 'p') 
    ->innerJoin(
     'AppBundle:ProductAttributes', 
     'pa', 
     'WITH', 
     'p.id = pa.productId' 
) 
    ->innerJoin(
     'AppBundle:ProductCategories', 
     'pc', 
     'WITH', 
     'pa.value = pc.id' 
) 
    ->where('pa.type = 1') 
    ->andWhere('pa.default = 1') 
    ->setMaxResults($limit); 

bemerke ich einen „UndWo“ verwenden, aber Ihre ursprüngliche hatte eine zusätzliche „where“. Ich bin überrascht, dass funktioniert und nicht geworfen und Fehler.

Auch ich denke, das Hauptproblem ist, dass Sie nur die zurückgegebenen Ergebnisse verstehen müssen. Dann in Ihrem Zweig, rufen Sie nicht das Attribut, sondern rufen Sie den Getter wie folgt:

// From index.twig.html 
{% for product in products %} 
    <h1>{{ product.getName }}</h1> 
{% endfor %} 

Können Sie diese Änderungen versuchen? Ich denke, das Aufrufen des Getters in der Twig-Vorlage ist das Problem.

Dies funktioniert möglicherweise nicht. Lass es uns wissen, wenn es nicht so ist.

+0

Wenn die Beziehungen alle zugeordnet sind, dann ist innerJoin ('p.attributes', 'pa') alles was benötigt wird. Es ist nicht notwendig, die Befehle mit dem Befehl zu definieren oder die Produktattributklasse anzugeben. – Cerad

+0

Ich sehe was du sagst @Cerad und ich stimme deinen Kommentaren (und damit dem Upvote) vollkommen zu. Die Funktionsweise von Symfony ist neu und ich gehe davon aus, dass seine Abfrage so funktioniert, wie sie ist. Nur versuchen zu helfen, dieses Problem zu lösen. Sobald er mit dem "einfacheren" Weg vertraut ist, kann er sein Design ändern. –

+0

@AlvinBunk, als ich versucht habe, zu {{product.getName}} zu wechseln und sogar die Klammer zur Funktion hinzugefügt habe, habe ich den gefürchteten Array-String-Konvertierungsfehler bekommen. Nach meinem Verständnis soll product.name eigentlich den Getter getName() aufrufen, aber im Falle dieser Art der Abfrage, wie Cerad sagte, hydratisiert es die Ergebnisse direkt in ein Array und verwendet die Getters nicht. – pogeybait

Verwandte Themen