在Symfony3的多对多关系表中,“检查是否存在”的最佳方法是什么?

时间:2019-01-07 13:25:51

标签: php symfony symfony-3.3

我对用户的实现很简单->收藏夹用户文章:

控制器:

/**
 * @Route("/articles/{category}/{id}/addtofavorites", name="addToFavourites")
 */
public function addToFavourites($category, $id)
{
    $em = $this->getDoctrine()->getManager();
    $article = $em->getRepository("AppBundle:Article")->find($id);
    $user = $this->getUser();
    $user = $em->getRepository("AppBundle:User")->find($user->getId());
    $user->addFavouriteArticle($article);
    $em->persist($user);
    $em->flush();

    $test = 'true';

    return new JsonResponse($test);
}

用户实体:

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 * @ORM\Table(name="user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     */
    private $firstName;

    /**
     * @var favouriteArticles[]
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Article", cascade={"all"})
     * @ORM\JoinTable(name="user_favourite_articles",
     *     joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="article_id", referencedColumnName="id")})
     */
    private $favouriteArticles;

    public function __construct() {
        $this->favouriteArticles = new ArrayCollection();
    }

    /**
     * @return favouriteArticles[]
     */
    public function getFavouriteArticles(): array
    {
        return $this->favouriteArticles->toArray();
    }

    /**
     * @param favouriteArticles[] $favouriteArticles
     */
    public function setFavouriteArticles(array $favouriteArticles): void
    {
        $this->favouriteArticles = $favouriteArticles;
    }

    /**
     * Add user
     *
     * @param \AppBundle\Entity\Article $article
     *
     * @return User
     */
    public function addFavouriteArticle(Article $article)
    {
        $this->favouriteArticles[] = $article;

        return $this;
    }

因此,我应该更改控制器方法,以检查数据库中是否已存在Article,并且再次单击Favourite button,它应该将其从DB中删除(此刻每次仅添加文章)。怎么做?如果它是普通表,我将添加到用户存储库中,如下所示:

return (boolean)$this->createQueryBuilder('u')
            ->andWhere('u.article = :article')
            ->setParameter('article', $rticle)
            ->getQuery()
            ->getOneOrNullResult();

但是在这种情况下,与ManyToMany关系我不知道如何以及在哪里做。

2 个答案:

答案 0 :(得分:1)

public function addFavouriteArticle(Article $article)
{
    if ($this->favouriteArticles->contains($article)) {
        return;
    }

    $article->setUser($this);
    $this->favouriteArticles[] = $article;
}

public function removeFavouriteArticle(Article $article)
{
    $this->favouriteArticles->removeElement($article);
}

This way user would never add same article to his favourites (because it aleady exists).

答案 1 :(得分:0)

Mr Zorpen wrote everything correctly, but I would have done a little differently. In my case, the method for checking "if exists" is separately from the addition. Plus, there is a check for the emptiness of the article.

/**
 * @param Article $article
 * @return bool
 */
public function isContainsArticle(Article $article)
{
    if ($this->favouriteArticles->contains($article)) {
        return true;
    }

    return false;
}

/**
 * @param Article $article
 * @return bool
 */
public function addArticle (Article $article)
{
    if (empty($article) || $this->isContainsArticle($article)) {
        return false;
    }
    $this->favouriteArticles->add($article);

    return true;
}

/**
 * @param Article $article
 */
public function removeArticle (Article $article)
{
    $this->favouriteArticles->removeElement($article);
}