Сохранение отношения Many to Many к базе данных в Symfony2

В моем проекте Symfony2 у меня есть два связанных объекта: "Пользователи" и "Избранное". У них есть отношения "многие-ко-многим".

Мое приложение работает следующим образом: На моей Twig-странице у меня есть несколько элементов с кнопкой "Добавить в избранное". Когда вы нажимаете кнопку, мой контроллер сохраняет item_id в столбце "Избранное". Но потом я хочу сэкономить пользователь, который добавил элемент в избранное, и здесь мое приложение не работает.

Пользователь и избранное существуют, но joincolumn между Users и Favorites остается пустым. Я также не получаю никаких ошибок.

Вот мой код:

Entity Users

class Users implements AdvancedUserInterface
{
    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Favorites", inversedBy="user", cascade={"persist"})
     * @ORM\JoinTable(name="user_has_favorite",
     *   joinColumns={
     *     @ORM\JoinColumn(name="user_id", referencedColumnName="user_id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="favorite_id", referencedColumnName="favorite_id")
     *   }
     * )
     */
    private $favorite;

    public function __construct()
    {
        $this->favorite = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function addFavorite(\Geo\CityTroopersBundle\Entity\Favorites $favorite)
    {
        $this->favorite[] = $favorite;

        return $this;
    }
...

Избранное объектов

class Favorites
{

    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     *
     * @ORM\ManyToMany(targetEntity="Users", mappedBy="favorite", cascade={"persist"})
     */
    private $user;

    public function __construct()
    {
        $this->user = new \Doctrine\Common\Collections\ArrayCollection();
    }
    public function addUser(\Geo\CityTroopersBundle\Entity\Users $user)
    {
        $this->user[] = $user;    
        return $this;
    }

Мой контроллер

public function showNewsAction()
    {
        $request = $this->get('request');    
        $itemId=$request->request->get('itemId');
        if($itemId != NULL)
        {
        //MAKE NEW FAVORITE AND ADD TO DATABASE LINKED WITH ITEM
        $favorite = new Favorites();
        $favorite->setItemId($itemId);

         //LINK FAVORITE ID WITH USER ID IN JOINCOLUMN
        $userId = 6;
        $em = $this->getDoctrine()->getEntityManager();

        $user = $em->getRepository('GeoCityTroopersBundle:Users')->find($userId);

        $favorite->addUser($user);
        $em->persist($favorite); 

        //I TRIED THIS TOO, BUT IT FAILED
        /*$user->addFavorite($favorite);
        $em->persist($user);*/

        $em->flush();

Ответы

Ответ 1

Ты был рядом. Для отношений доктрины "многие-ко-многим" вам нужно вызвать оба метода добавления

$favorite->addUser($user);
$user->addFavorite($favorite);

$em->persist($favorite); 
$em->persist($user);
$em->flush();

Это должно сделать трюк. В docs они делают это, но не упоминайте об этом слишком явно. Не уверен, почему либо потому, что многие люди сталкиваются с этим (включая меня).

Ответ 3

Как указано Седриком, добавление записи для отношения многих ко многим осуществляется только в одном направлении, и это зависит от того, как вы определили отношение: добавление может выполняться только родительским объектом отношения, поэтому в вашем случае вы должны использовать:

$user->addFavorite($favorite);

Ответ 4

В вашей строке:

@ORM\JoinColumn(name="favorite_id", referencedColumnName="favorite_id")

name="favorite_id"
Часть

относится к столбцам в таблице соединений, тогда как

referencedColumnName="favorite_id"

ссылается на идентификатор в любимой таблице, который обычно является просто "id". Вы должны попробовать:

    /**
 * @var \Doctrine\Common\Collections\ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="Favorites", inversedBy="user", cascade={"persist"})
 * @ORM\JoinTable(name="user_has_favorite",
 *   joinColumns={
 *     @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="favorite_id", referencedColumnName="id")
 *   }
 * )
 */
private $favorite;