2016-07-31 6 views
1
funktioniert

Um problem I asked about earlier zu lösen, ich versuche, eine benutzerdefinierte Repository-Funktion zu erstellen, ob eine Instanz von Repair einzigartig bestimmen ist, auf der Grundlage der device, name und colors Einschränkungen .Lehre: Benutzerdefinierte Repository, um zu bestimmen UniqueEntity nicht

Hier ist mein Doctrine Annotation für Klasse Repair. Beachten Sie, dass die device-Eigenschaft "Viele zu Eins" (viele Reparaturen für ein Gerät) lautet und dass colors "Viele zu viele" lautet.

/** 
* @ORM\Table(name="repair") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\RepairRepository") 
* @UniqueEntity(fields={"name", "device", "colors"}, repositoryMethod="getSimilarRepairs", message="Repair {{ value }} already exists for this name, device and colour combination.") 
*/ 

Das ist mein RepairRepository.php, in denen $criteria['colors'] ein Array ist.

public function getSimilarRepairs(array $criteria) { 
    $builder = $this->createQueryBuilder('r') 
     ->where('r.device = :device') 
     ->andWhere('r.colors = :colors') 
     ->andWhere('r.name = :name') 
     ->setParameters(['deviceid'=>$criteria['device'],'colors'=>$criteria['colors'],'name'=>$criteria['name']]); 
    return $builder->getQuery(); 
} 

Ich habe drei Probleme, die wahrscheinlich auf eine gebracht werden kann:

  • Redaktion: bei jeder Änderung, so dass eine doppelte oder nicht, bekomme ich die Meldung, dass ein Duplikat Einheit existiert.
  • editieren: Trotz der Fehlermeldung werden Namensänderungen trotzdem durchgeführt!
  • hinzufügen: Ich kann so viele Duplikate erstellen, wie ich möchte, es gibt nie eine Fehlermeldung.
+0

Siehst du diesen Beitrag? http://stackoverflow.com/questions/16148678/symfony-2-uniqueentity-repositorymethod-fails-on-update-entity – DOZ

+0

Yous benutzerdefinierte Abfrage funktioniert genauso wie die Standardabfrage. Es ist normal, dass es nicht funktioniert :) Ich werde es versuchen. – Alsatian

Antwort

0

Ihr Problem ist, dass die Farben Beziehung eine ManyToMany ist. In SQL können Sie in dieser Beziehung nicht '=' abfragen.

Es ist sehr kompliziert, deshalb kann Doctrine (und wir wahrscheinlich) es nicht alleine schaffen.

Eine Teillösung eine Abfrage zu erstellen:

public function getSimilarRepairs(array $criteria) { 
    $builder = $this->createQueryBuilder('r') 
     ->where('r.device = :device') 
     ->andWhere('r.name = :name')->setParameter('name',$criteria['name']) 
     ->andWhere('r.colors = :colors')->setParameter('deviceid',$criteria['device']); 

    // r matches only if each of your colors exists are related to r : 
    $i=0; 
    foreach($criteria['colors'] as $color){ 
     $i++; 
     $builder->join('r.colors','c'.$i)->andWhere('c = :color'.$i)->setParameter('color'.$i,$color); 
    } 

    // Then you had also to check than there is no other color related to r : 

    // I don't know how 


    return $builder->getQuery(); 
} 

Aber lassen Sie mich schlagen eine andere Lösung:

In Ihrer Reparatur Einheit, Ihre ein Duplikat Ihrer verwandten Farben speichern kann:

/** 
* @var string 
* 
* @ORM\Column(name="name_canonical", type="string") 
*/ 
private $serializedColors; 

setzen Sie es mit Doktrin Lifecycle-Ereignisse:

/** 
* @ORM\PrePersist 
* @ORM\PreUpdate 
*/ 
public function updateColors() 
{ 
    $serializedColors = ''; 

    foreach($this->colors as $color){ 
     $serializedColors .= $color->getId().'#'; 
    } 

    $this->serializedColors = $serializedColors; 
} 

Vergessen Sie nicht @HasLifecycleCallbacks

Dann ändern Sie Ihre UniqueEntityConstraint zu fields={"name", "device", "serializedColors"}, vergessen Sie die benutzerdefinierte Abfrage, und es wird funktionieren hinzuzufügen.

+0

Das ist eine sehr interessante Lösung @Alsatian. Ich habe nie so darüber nachgedacht. Es fühlt sich ein wenig "schmutzig" an, speichert Daten für den reinen Zweck, der Logik umgeht, aber ich gehe davon aus, dass es die Leistung erhöht. Danke, ich probiere es gleich aus und melde mich bald wieder. – bluppfisk

+0

YEs es ist schmutzig, aber ich habe nie besser für diese Verwendung gefunden. – Alsatian

Verwandte Themen