prudkovski
@prudkovski

Удаление связей many-to-many с промежуточной таблицей?

Добрый день всем.

Не получается удалить связи many-to-many с промежуточной таблицей, не могу понять - что не так.

Есть сущности "Пользователь", "Подписка" и "ПодпискиПользователей"
У пользователя может быть несколько подписок, подписка может принадлежать нескольким пользователям.

Есть форма где выводятся все доступные подписки с возможностью отметить желаемые.

Далее код.

Сущность Пользователь
<?php
// src/Pet/UserBundle/Entity/User.php

namespace Pet\UserBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Pet\UserBundle\Entity\UserMailing;

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

    /**
     * @ORM\OneToMany(targetEntity="UserMailing", mappedBy="user", cascade={"all"})
     * */
    protected $user_mailing;

    protected $mailings;
}

    public function __construct()
    {
        parent::__construct();
        $this->user_mailing = new ArrayCollection();
        $this->mailings = new ArrayCollection();
    }

public function getMailing()
    {
        $mailings = new ArrayCollection();

        foreach ($this->user_mailing as $um) {
            $mailings[] = $um->getMailing();
        }

        return $mailings;
    }

    public function setMailing($mailings)
    {
        foreach($mailings as $m)
        {
            $user_mailing = new UserMailing();

            $user_mailing->setUser($this);
            $user_mailing->setMailing($m);

            $this->addUserMailing($user_mailing);
        }

    }

    public function addUserMailing($userMailing)
    {
        $this->user_mailing[] = $userMailing;
    }
    
    public function removeUserMailing($userMailing)
    {
        $this->user_mailing->removeElement($userMailing);
    }
}


Сущность Подписка
<?php

namespace Pet\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Pet\UserBundle\Entity\User;

/**
 * @ORM\Entity
 * @ORM\Table(name="mailings")
 */
class Mailing
{

	/**
	 * @ORM\Column(name="id", type="integer")
	 * @ORM\Id
	 * @ORM\GeneratedValue(strategy="IDENTITY")
	 */
	protected $id;

	/**
	 * @ORM\Column(type="string", length=100)
	 */
	protected $name;

	/**
	 * @ORM\OneToMany(targetEntity="UserMailing" , mappedBy="mailing" , cascade={"all"})
	 * */
	protected $user_mailing;

	public function getName()
	{
		return $this->name;
	}

	public function setName($name)
	{
		$this->name = $name;
		return $this->name;
	}

}


Сущность ПодпискаПользователя
<?php

namespace Pet\UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Pet\UserBundle\Entity\User;
use Pet\UserBundle\Entity\Mailing;


/**
 * @ORM\Entity
 * @ORM\Table(name="user_mailings")
 * @ORM\HasLifecycleCallbacks()
 */
class UserMailing
{
	/**
	 * @ORM\Column(name="id", type="integer")
	 * @ORM\Id
	 * @ORM\GeneratedValue(strategy="IDENTITY")
	 */
	protected $id;

	/**
	 * @ORM\ManyToOne(targetEntity="Mailing", inversedBy="user_mailing")
	 * @ORM\JoinColumn(name="mailing_id", referencedColumnName="id")
	 * */
	protected $mailing;

	/**
	 * @ORM\ManyToOne(targetEntity="User", inversedBy="user_mailing")
	 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
	 * */
	protected $user;


	public function setUser(User $user = null)
	{
		$this->user = $user;

		return $this;
	}

	public function setMailing(Mailing $mailing = null)
	{
        $this->mailing = $mailing;

        return $this;
	}

	public function getUser()
	{
		return $this->user;
	}

	public function getMailing()
	{
		return $this->mailing;
	}
}


Форма

<?php

namespace Pet\UserBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class MailingFormType extends AbstractType
{
	public function buildForm(FormBuilderInterface $builder, array $options)
	{
	    $builder->add('mailing', 'entity', array(
	        'class' => 'PetUserBundle:Mailing',
	        'property' => 'name',
	        'multiple' => true,
	        'expanded' => true,
	        'label' => 'form.mailing', 'translation_domain' => 'PetUserBundle',
	    ));




	}

	public function getName()
	{
	    return 'formMailing';
	}

	public function getDefaultOptions(array $options)
	{
	    return array(
	        'data_class' => 'Pet\UserBundle\Entity\User'
	    );
	}
}


Контроллер
public function showMailingAction()
    {
        $user = $this->container->get('security.context')->getToken()->getUser();
        if (!is_object($user) || !$user instanceof UserInterface) {
            throw new AccessDeniedException('This user does not have access to this section.');
        }

        $form = $this->container->get('form.factory')->create(new MailingFormType(), $user); 
        
        $previousCollections = $user->getMailing();
        $previousCollections = $previousCollections->toArray();

        $request = $this->container->get('request');
        if ($request->getMethod() == 'POST')
        {

            $form->bind($request);

            if ($form->isValid())
            {   
                foreach($previousCollections as $um)
                {   
                    $user->removeUserMailing($um);
                }    
                
                $em->persist($user);
                $em->flush();
                $this->setFlash('pet_user_success', 'profile.flash.updated');
                return new RedirectResponse($this->getRedirectionUrl($user));
            } 
        }

        return $this->container->get('templating')->renderResponse('PetUserBundle:Profile:subscriptions.html.'.$this->container->getParameter('fos_user.template.engine'), 
               array(
                     'form' => $form->createView(),
                     )
               );

    }


На странице формы отображается список с чекбоксами подписок. Если отметить их - в user_mailings все отлично добавляется. Но вот если снять галочки и отправить форму, не происходит удаление из user_mailings записей. Если повторно отправить форму с отмеченными подписками то они повторно запишутся. Такие дела.

Не могу сообразить почему не удаляется, почему не отрабатывается метод removeUserMailing
  • Вопрос задан
  • 2983 просмотра
Пригласить эксперта
Ответы на вопрос 1
@jaxel
Для удаления записей, с которым разорвана связь нужно добавить в аннотации orphanRemoval=true

Если ты хочешь просто разрывать связь, то у тебя главной стороной связи должна быть та, с которой связь управляется.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы