我在 Symfony 3.4 上有一个奇怪的问题
我澄清一下情况:我有两个实体:
用户类型 和包。 目标是根据用户类型向我的用户提供包(用户只会看到与其用户类型对应的包)。
一个包可以属于多个用户类型,一个用户类型可以有多个包。
所以我有一个 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
}
编辑:看看我的架构:
最佳答案
看来您正在删除包,而不是 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 上)并将孤儿学说属性选中为"is",则此代码将由学说生成。
第二种方法包括手动执行并调用您的 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();
}
但这种方法不是一个好的做法。
关于php - Symfony 3 - 我的实体存在 ManyToMany 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56005478/