Symfony 3 - 如何防止sql表出现重复行

时间:2017-05-28 16:35:49

标签: php mysql symfony symfony-3.2

我正在Symfony3中创建API,我的情况是用户可以将游戏添加到他的堆栈中。所以我有连接用户ID和游戏ID的表,但是当我向DB添加行时,可能存在重复的情况,例如:

duplicates

我想避免这种情况,但该怎么做?是否有一些类似symfony3的方法来预防这种情况?或者我应该在端点中添加一些if-else语句并返回一些成功的JSON:false?无论如何,我该怎么办?我正在寻找最简单或最有效的方式。

该实体的代码如下:

<?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;
    }

}

和REST端点:

<?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));

    }
}

1 个答案:

答案 0 :(得分:2)

UniqueEntity约束添加到您的实体并使用控制器中的validator service验证对象:

<强>的appbundle /实体/ 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 /控制器/ 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));
    }

}