Symfony 3-我的实体的ManyToMany问题

时间:2019-05-06 12:40:09

标签: php symfony many-to-many

我在Symfony 3.4上有一个奇怪的问题

我澄清了这种情况:我有两个实体:

UserType Package 。 目的是根据用户的类型向我的用户提供软件包(用户只会看到与他们的用户类型相对应的软件包)。

一个包可以属于多个用户类型,一个用户类型可以有多个包。

所以我有一个ManyToMany关系。

TypeUser.php     

namespace Site\PagesBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * TypeUser
 *
 * @ORM\Table(name="type_user")
 * @ORM\Entity(repositoryClass="Site\PagesBundle\Repository\TypeUserRepository")
 */
class TypeUser
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="typeUtilisateur", type="string", length=255)
     */
    private $typeUtilisateur;


    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set typeUtilisateur
     *
     * @param string $typeUtilisateur
     *
     * @return TypeUser
     */
    public function setTypeUtilisateur($typeUtilisateur)
    {
        $this->typeUtilisateur = $typeUtilisateur;

        return $this;
    }

    /**
     * Get typeUtilisateur
     *
     * @return string
     */
    public function getTypeUtilisateur()
    {
        return $this->typeUtilisateur;
    }
}

Paquet.php:

<?php
namespace Site\PagesBundle\Entity;
//use
/**
 * Paquet
 *
 * @ORM\Table(name="paquet")
 * @ORM\Entity(repositoryClass="Site\PagesBundle\Repository\PaquetRepository")
 * @Vich\Uploadable
 */
class Paquet
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**  
     * @var \Doctrine\Common\Collections\Collection
     * @ORM\ManyToMany(targetEntity="TypeUser")  
     * @ORM\JoinTable(name="Packages_des_TypesUser") 
     * @ORM\JoinColumn(nullable=false)
     */  
    private $typeUser;
    public function __construct()
    {
        $this->typeUser = new ArrayCollection();
    }
    /** 
     * Get TypeUser 
     * 
     * @return Site\PagesBundle\Entity\TypeUser 
     */ 
    public function getTypeUser() 
    { 
        return $this->typeUser; 
    }
    public function deleteTypeFromTypesUser(TypeUser $type)
    {
        $this->typeUser->removeElement($type);
    }
    /**
     * Set typeUser
     *
     * @param Site\PagesBundle\Entity\TypeUser $typeUser
     *
     * @return Paquet
     */
    public function setTypeUser(Site\PagesBundle\Entity\TypeUser $typeUser)
    {
        $this->typeUser = $typeUser;
        return $this;
    }
    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
}

因此,当我添加一个包时,我可以选择一些TypeUser:

enter image description here

当我管理软件包时:

enter image description here

现在,如果我想通过添加用户类型来修改软件包,则会出现问题:

我有我的包裹:让我们通过单击“修饰符”添加一个新的TypeUser

enter image description here

让我们检查“ DAFPIC”:

enter image description here

好吧,我现在也拥有DAFPIC上的软件包,在数据库上的关联上有新行:

enter image description here enter image description here

但是现在,如果我从DAFPIC新软件包中单击“ Supprimer”,则如果转储此软件包的TypeUser,则会得到第一个typeUser:

enter image description here

所以,我不明白怎么了...有人可以帮我吗?

编辑:

当我单击删除按钮时:

/**
     * Suppression d'un package | Suppression d'un type d'utilisateur attribué à un package
     *
     * @Route("/{id}/{type}/delete", name="paquets_delete")
     */
    public function deleteAction(Request $request, $id, $type)
    {
        $em = $this->getDoctrine()->getManager();
        $unPaquet = $em->getRepository('PagesBundle:Paquet')->find($id); //Récupération du package
        $leType = $em->getRepository('PagesBundle:TypeUser')->findOneByTypeUtilisateur($type);
        dump($leType);

        $em->remove($unPaquet);

        return $this->redirectToRoute('paquets_index'); // Actualisation de la page
}

编辑:看一下我的架构:

enter image description here

1 个答案:

答案 0 :(得分:1)

似乎您要删除软件包,而不是删除Paquet和UserType之间的关联UserTypePaquet。

USER_TYPE <== USER_TYPE_PAQUET ==> PAQUET.
                    ^^               ^^
                    ||               ||
                    ||               ||
          you should delete this     ||
                                     ||
              you are currently deleting this 

(您也肯定会删除与软件包的所有关联)

您必须选择与此用户关联的所有软件包(通过使用getPaquets()调用集合)并删除其中的一个元素即相关的软件包。

    /**
     * Suppression d'un package | Suppression d'un type d'utilisateur attribué à un package
     *
     * @Route("/{id}/{type}/delete", name="paquets_delete")
     */
    public function deleteAction(Request $request, $id, $type)
    {
        $em = $this->getDoctrine()->getManager();
        $unPaquet = $em->getRepository('PagesBundle:Paquet')->find($id); //Récupération du package
        $leType = $em->getRepository('PagesBundle:TypeUser')->findOneByTypeUtilisateur($type);
        dump($leType);

        //$em->remove($unPaquet); <=== DO NOT remove THE PAQUET
        $leType->getPaquets()->remove($unPaquet);// <=== Remove only the paquet associated to user
        $em->persist($leType); //Then save $leType sans le paquet associé
        $em->flush();

        return $this->redirectToRoute('paquets_index'); // Actualisation de la page
    }

此解决方案是解决您的问题的第一步。现在您必须删除使用PaquetDDLCas实体。您有两种解决方案:第一种(更好的解决方案)也是更新数据库架构,以在PaquetDDLCas上将PaquetDDLCas链接到PackageTypeUser的外键上添加“删除时级联”约束。

ALTER TABLE PaquetDDLCas ADD CONSTRAINT FK_xxxx FOREIGN KEY (paquet_id, type_user_id) REFERENCES Package_typeuser (paquet_id, type_user_id) ON DELETE CASCADE')

如果您正确地将PaquetDDLCas链接到PaquetTypeUser(并删除了两个链接,一个链接在Paquet上,另一个链接在PaquetTypeUser上),并且将孤立的主义属性指定为“是”,则该代码将由主义生成。

第二种方法是手动执行此操作并调用PaquetDDLCasRepository并创建一个删除所有数据的新函数。


public function deleteByPaquetAndTypeUser($paquet,$user)
{
    $qb = $this->createQueryBuilder('p')
    $qb->delete()
       ->where('p.user = :user')
       ->andWhere('p.paquet = :paquet')
       ->setParameter('user', $user)
       ->setParameter('paquet', $paquet)
       ->getQuery()
       ->getResult();
}

但是这种方法不是一个好习惯。