P
P
Prudkovski2014-11-21 18:56:09
symfony
Prudkovski, 2014-11-21 18:56:09

Deleting many-to-many relationships with an intermediate table?

Good day to all.
I can't delete many-to-many relationships with an intermediate table, I can't figure out what's wrong.
There are entities "User", "Subscription" and "SubscriptionsUsers"
A user can have several subscriptions, a subscription can belong to several users.
There is a form where all available subscriptions are displayed with the ability to mark the desired ones.
Further code.
Entity User

<?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);
    }
}

Entity Subscription
<?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;
  }

}

EntityUserSubscription
<?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;
  }
}

The form
<?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'
      );
  }
}

Controller
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(),
                     )
               );

    }

The form page displays a list with subscription checkboxes. If you mark them, everything is perfectly added to user_mailings. But if you uncheck the boxes and submit the form, there is no deletion from user_mailings records. If you resubmit the form with marked subscriptions, they will be re-recorded. So it goes.
I can’t figure out why it’s not removed, why the removeUserMailing method is not processed

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jaxel, 2014-12-17
@jaxel

To delete records with which the connection is broken, you need to add orphanRemoval=true to the annotations.
If you just want to break the connection, then your main side of the connection should be the one with which the connection is controlled.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question