在 Symfony3 的多对多关系 table 中“检查是否存在”的最佳方法是什么?
Which is the best way to 'check if exists` in many to many relationship table in Symfony3?
我简单实现了用户->收藏夹用户文章:
控制器:
/**
* @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;
}
所以我应该更改控制器方法来检查文章是否已经存在于数据库中并且再次单击 Favourite button
它应该将其从数据库中删除(目前它每次都只是添加文章)。怎么做?如果是正常的 table 我会添加到 User Repository 中,像这样:
return (boolean)$this->createQueryBuilder('u')
->andWhere('u.article = :article')
->setParameter('article', $rticle)
->getQuery()
->getOneOrNullResult();
但是在这种多对多关系的情况下,我不知道如何以及在哪里做。
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);
}
这样用户就不会将同一篇文章添加到他的收藏夹中(因为它已经存在)。
Zorpen 先生写的一切都正确,但我会做得有点不同。就我而言,检查 "if exists" 的方法与添加分开。另外,还有文章是否为空的检查。
/**
* @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);
}
我简单实现了用户->收藏夹用户文章:
控制器:
/**
* @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;
}
所以我应该更改控制器方法来检查文章是否已经存在于数据库中并且再次单击 Favourite button
它应该将其从数据库中删除(目前它每次都只是添加文章)。怎么做?如果是正常的 table 我会添加到 User Repository 中,像这样:
return (boolean)$this->createQueryBuilder('u')
->andWhere('u.article = :article')
->setParameter('article', $rticle)
->getQuery()
->getOneOrNullResult();
但是在这种多对多关系的情况下,我不知道如何以及在哪里做。
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);
}
这样用户就不会将同一篇文章添加到他的收藏夹中(因为它已经存在)。
Zorpen 先生写的一切都正确,但我会做得有点不同。就我而言,检查 "if exists" 的方法与添加分开。另外,还有文章是否为空的检查。
/**
* @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);
}