我在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:
当我管理软件包时:
现在,如果我想通过添加用户类型来修改软件包,则会出现问题:
我有我的包裹:让我们通过单击“修饰符”添加一个新的TypeUser
让我们检查“ DAFPIC”:
好吧,我现在也拥有DAFPIC上的软件包,在数据库上的关联上有新行:
但是现在,如果我从DAFPIC新软件包中单击“ Supprimer”,则如果转储此软件包的TypeUser,则会得到第一个typeUser:
所以,我不明白怎么了...有人可以帮我吗?
编辑:
当我单击删除按钮时:
/**
* 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
}
编辑:看一下我的架构:
答案 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();
}
但是这种方法不是一个好习惯。