【发布时间】:2013-03-26 11:11:43
【问题描述】:
我做了一些研究,在阅读了 this 和 this(以及所有相关问题)之后,我仍然无法确定在 Symonfy 2 Doctrine 中更新多对多关系的正确方法。感觉应该有一个很简单的方法我还没有找到。
我有这 2 个实体:
class student_main
{
/**
* @ORM\ManyToMany(targetEntity="support_log", inversedBy="student_main")
* @ORM\JoinTable(name="support_log_student")
**/
private $support_log;
和
class support_log
{
/**
* @ORM\ManyToMany(targetEntity="student_main", mappedBy="support_log")
**/
private $student;
我想从support_log开始。在控制器中,在更新操作中,我有类似的东西:
if ($editForm->isValid()) {
//add the relationship the user added
foreach($students as $student){
if(!$em->getRepository('mybundle:student_main')->hasSupportLog($entity,$student)){
$entity->addstudent_main($student);//*
}
}
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('support_log_edit', array('id' => $id)));
}
当然,正如教义文档所说,我相应地更改了该函数 (addstudent_main):
public function addstudent_main(student_main $student)
{
$student->addsupport_log($this); // the important addition
$this->student[] = $student;
}
这很好用,我的问题更多是关于删除关系。在表单中有一个多选,用户可能会选择一些已经相关的学生和一些不相关的学生。感觉应该有一种自动的方式来做到这一点,但我不得不做很多代码。
在控制器中,略高于我之前写的代码,我写的是:
//delete all old relationship
foreach($idsldstudents as $idst){ //I take Id's because the doctrine collection is updating always..
$stu=$em->getRepository('MyBundle:student_main')->find($idst);
$stu->deletesupport_log($entity);//I had to create that method (in the entity, I do "$this->support_log->removeElement($support_log)")
$em->persist($stu);
$em->flush();
}
我删除了相关实体的所有关系(当然要注意是双向关系,所以必须先在另一边删除),然后再添加用户选择的关系.
还有其他方法可以做到这一点,但我还没有找到任何简单的方法。在所有这些中,我都有相同的问题:
- 我需要一直检查关系是否存在
- 我需要获取旧关系(这很困难)并与用户指示的新关系进行比较,然后相应地删除或创建
有没有办法自动解决这两个问题? (我有一种强烈的感觉,那就是一定有——也许可以更好地声明这种关系?——这就是我问的原因。
提前致谢
编辑: 我的表单没有什么特别的,我想我什至没有触摸生成的代码。它显示了我想要的多选,Symfony2 的默认设置,你必须使用 ctrl 键来选择多个。代码如下:
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('student')
...
;
}
关键靠这里?
【问题讨论】:
-
第一个想法是使用 $student->supportLog->clear();而不是循环。但这不是答案,只是改进。二是表单可以自动管理集合。请显示您的表单类型的代码。
-
第一个想法带来了非常有价值的改进,它更加优雅!谢谢!对于表格,是Symfony生成的平面,我什至没有碰我想,看看编辑请@DmitryKrasun
-
(只是一个注释,在 supportlog 控制器中: $student->supportLog->clear(); 不起作用,因为它会删除学生拥有的所有关系,我只想删除一个关系,以及我当前正在编辑的支持日志(循环是对已经与我当前正在编辑的此支持日志相关的所有其他学生执行相同操作)
-
我把它放在这里了,因为我没有特定于 symfony 的解决方案。这应该阐明如何在实体级别处理多对多:gist.github.com/3121916
标签: php symfony doctrine-orm many-to-many bidirectional