Какой лучший способ «проверить, существует ли» в таблице отношений «многие ко многим» в Symfony3? - PullRequest
0 голосов
/ 07 января 2019

У меня есть простая реализация User -> Favorites User Articles:

Контроллер:

/**
 * @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 голосов
/ 07 января 2019

Мистер Зорпен написал все правильно, но я бы поступил немного иначе. В моем случае метод проверки «если существует» - это отдельно от дополнения. Плюс есть проверка на пустоту статьи.

/**
 * @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);
}
0 голосов
/ 07 января 2019
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);
}

Таким образом, пользователь никогда не добавит ту же статью в избранное (потому что она существует).

...