2017-05-28 1 views
0

Ich erstelle API in Symfony3 und ich habe eine Situation, in der der Benutzer Spiele seinem Stapel hinzufügen kann. So habe ich die Tabelle, die User-ID und Spiel ids verbindet, aber wenn ich Zeilen bin Hinzufügen mit, dass in den DB kann es eine Situation, wo es Duplikate sein können, wie:Symfony 3 - wie man sql Tabelle von doppelten Reihen verhindert

duplicates

Ich möchte vermeiden diese Situation, aber wie? Gibt es einige symfony3-ähnliche Möglichkeiten, um diese Art von Situation zu verhindern? Oder sollte ich einige if-else-Anweisungen auf dem Endpunkt hinzufügen und einen JSON mit Erfolg zurückgeben: false? Wie auch immer, wie kann ich es tun? Ich suche den einfachsten oder den effizientesten Weg.

Der Code des Unternehmens wie folgt aussieht:

<?php 
namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 

/** 
* @ORM\Entity 
* @ORM\Table(name="games_on_stacks") 
*/ 
class GamesOnStacks 
{ 
    /** 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @ORM\Column(type="integer") 
    */ 
    private $id; 
    /** 
    * @ORM\ManyToOne(targetEntity="User") 
    * 
    */ 
    private $user; 

    /** 
    * @return mixed 
    */ 
    public function getUser() 
    { 
     return $this->user; 
    } 

    /** 
    * @param mixed $user 
    */ 
    public function setUser(User $user) 
    { 
     $this->user = $user; 
    } 

    /** 
    * @ORM\ManyToOne(targetEntity="Game") 
    */ 
    private $game; 

    /** 
    * @return mixed 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getGame() 
    { 
     return $this->game; 
    } 

    /** 
    * @param mixed $game 
    */ 
    public function setGame($game) 
    { 
     $this->game = $game; 
    } 

} 

und der REST-Endpunkt:

<?php 


namespace AppBundle\Controller; 

use AppBundle\Entity\Game; 
use AppBundle\Entity\GamesOnStacks; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\JsonResponse; 
use Symfony\Component\HttpFoundation\Response; 

class GameController extends Controller 
{ 
    (...) 

    /** 
    * @Route("/game/{gameId}/add", name="game_add_to_stack") 
    */ 
    public function addToStack($gameId) 
    { 
     $gameOnStack = new GamesOnStacks(); 
     // db apply 
     $em = $this->getDoctrine()->getManager(); 
     $game = $em->getRepository('AppBundle:Game') 
      ->findOneBy(['id' => $gameId]); 
     $gameOnStack->setGame($game); 
     $user = $em->getRepository('AppBundle:User') 
      ->findOneBy(['id' => 1]); 
     $gameOnStack->setUser($user); 
     $em->persist($gameOnStack); 
     $em->flush(); 
     $arr = array('success' => true); 

     return new JsonResponse(json_encode((array)$arr)); 

    } 
} 
+0

Sie für bestehende 'GamesOnStacks' aussehen kann und nur speichern, wenn es keine gibt. Darüber hinaus können Sie eine [Einschränkung für Datenbankebene] (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-uniqueconstraint) festlegen. –

+0

@MateuszSip OK, aber wie geht das? Ich habe versucht: '@UniqueEntity ( * Felder = { "user", "Spiel"}, * errorPath = "Spiel", * message = "Dieses Spiel bereits zu diesem User-Stack hinzugefügt wird." *) ' hinzufügen unter der' @ORM \ Table (name = "games_on_stacks") Zeile, aber es hat nicht funktioniert. –

+0

'@ UniqueEntity' ist eine andere Sache im Zusammenhang mit [Validator-Komponente] (https://symfony.com/doc/current/validation.html). Einschränkung, die ich erwähnt habe, benötigt Schema-Aktualisierung/Migration (und es lohnt sich). Sie können beide verwenden (Es ist gut, diese Art von Validierung sowohl auf Anwendungs- als auch auf Datenbankebene einzuführen) oder "@ UniqueEntity" durch eine manuelle Prüfung mit Repository-Methode zu ersetzen (dies ist expliziter, würde aber bei korrekter Implementierung gleich funktionieren). In symfony docs ist alles gut dokumentiert, Sie sollten also etwas Zeit mit Lesen verbringen, und Sie sollten Ihr Problem ohne Probleme bewältigen. –

Antwort

2

die UniqueEntity Einschränkung zu Ihrem Unternehmen hinzufügen und das Objekt mit den validator service in Ihrem Controller bestätigen:

AppBundle/Entity/GamesOnStacks.php

<?php 
namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; 

/** 
* @ORM\Entity 
* @ORM\Table(name="games_on_stacks") 
* 
* @UniqueEntity(fields={"user", "game"}, errorPath="game", message="This game is already added on this user stack.") 
*/ 
class GamesOnStacks 
{ 
... 
} 

AppBundle/Controller/Gamecontroller

/** 
* @Route("/game/{gameId}/add", name="game_add_to_stack") 
*/ 
public function addToStack($gameId) 
{ 
    $gameOnStack = new GamesOnStacks(); 
    // db apply 
    $em = $this->getDoctrine()->getManager(); 
    $game = $em->getRepository('AppBundle:Game') 
     ->findOneBy(['id' => $gameId]); 
    $gameOnStack->setGame($game); 
    $user = $em->getRepository('AppBundle:User') 
     ->findOneBy(['id' => 1]); 
    $gameOnStack->setUser($user); 

    // validate using the validator service 
    $validator = $this->get('validator'); 
    $errors = $validator->validate($gameOnStack); 

    if (count($errors) > 0) { 

     // custom error handling, e.g. returning failure jsonreponse, etc. 
     $errorsString = (string) $errors;   

    } else { 

     $em->persist($gameOnStack); 
     $em->flush(); 
     $arr = array('success' => true); 


     return new JsonResponse(json_encode((array)$arr)); 
    } 

} 
+0

Danke! Das war genau das, was ich gesucht habe;) Ich habe die Fehlerbehandlung auf diese Weise erstellt: 'if (count ($ errors)> 0) { $ errorsString = ''; foreach ($ Fehler als $ Fehler) { $ errorsString. = $ Error-> getMessage(); } $ errArr = array ( 'Erfolg' => falsch, 'Fehler' => $ errorsString ); return new JsonResponse (json_encode ((array) $ errArr)); } ' –

Verwandte Themen