Reputation: 47
I have simple implementation of User -> Favourites User Articles:
Controller:
/**
* @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);
}
User Entity:
<?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;
}
So I should change controller method to check if Article already exists in DB and Favourite button
is clicked again it should remove it from DB (at the moment it just add article every time). How to do it? If it was normal table I would add in User Repository, like this:
return (boolean)$this->createQueryBuilder('u')
->andWhere('u.article = :article')
->setParameter('article', $rticle)
->getQuery()
->getOneOrNullResult();
But in this case with ManyToMany relation I don't know how and where to do it.
Upvotes: 1
Views: 1405
Reputation: 41
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);
}
Upvotes: 0
Reputation: 445
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).
Upvotes: 3