php – Symfony表单不保存与ManyToMany关系的实体
我有与ManyToMany关系保存实体槽形式的问题.
我无法保存关系“mappedBy”一侧的字段. 下面的代码不会将任何内容保存到数据库中,也不会丢失任何错误: // Entity/Pet /** * @var DoctrineCommonCollectionsCollection * * @ORMManyToMany(targetEntity="AppBundleEntityCustomer",mappedBy="pet",cascade={"persist"}) */ private $customer; /** * Set customer * * @param AppBundleEntityCustomer $customer * @return Pet */ public function setCustomer($customer) { $this->customer = $customer; return $this; } // Entity/Customer /** * @var Pet * * @ORMManyToMany(targetEntity="AppBundleEntityPet",inversedBy="customer",cascade={"persist"}) * @ORMJoinTable(name="customer_pet",* joinColumns={ * @ORMJoinColumn(name="customer_id",referencedColumnName="id") * },* inverseJoinColumns={ * @ORMJoinColumn(name="pet_id",referencedColumnName="id") * } * ) */ private $pet; // PetType.php $builder->add('customer','entity',array( 'class' => 'AppBundle:Customer','property' => 'firstname','empty_value' => 'Choose owner','multiple' => true )); 它反过来工作.因此,如果我从CustomerType中保存一些东西,那么一切正常. 编辑: 下面的解决方案对我有用,但几天后我发现该解决方案存在问题.如果将使用已保存在数据库中的值提交表单,则Symfony将抛出错误.为了防止我必须检查给定的客户是否已经分配给宠物. 检查当前分配的客户必须在功能开始时而不是在表单提交之后完成,因为在提交之后由于某种原因,Pet()对象包含提交的值,而不仅仅是存在于db中的值. 所以一开始我把所有已经分配的客户都放到了阵列中 $em = $this->getDoctrine()->getManager(); $pet = $em->getRepository('AppBundle:Pet')->find($id); $petOriginalOwners = array(); foreach ($pet->getCustomer() as $petCustomer) { $petOriginalOwners[] = $petCustomer->getId(); } 在表单提交后,我检查了提交的ID是否在数组中 if ($form->isValid()) { foreach ($form['customer']->getData()->getValues() as $v) { $customer = $em->getRepository('AppBundle:Customer')->find($v->getId()); if ($customer && !in_array($v->getId(),$petOriginalOwners) ) { $customer->addPet($pet); } } $em->persist($pet); $em->flush(); return $this->redirect($this->generateUrl('path')); } 解决方法
在Symfony2中,具有withversedBy教义注释的属性的实体是应该编辑由MANYTOMANY RELATION创建的EXTRA TABLE的实体.这就是为什么当您创建客户时,它会在该额外表中插入相应的行,从而保存相应的宠物.
如果你想以相反的方式发生相同的行为,我建议: //PetController.php public function createAction(Request $request) { $entity = new Pet(); $form = $this->createCreateForm($entity); $form->submit($request); if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); foreach ($form['customer']->getData()->getValues() as $v) { $customer = $em->getRepository('AppBundle:Customer')->find($v->getId()); if ($customer) { $customer->addPet($entity); } } $em->persist($entity); $em->flush(); return $this->redirect($this->generateUrl('pet_show',array('id' => $entity->getId()))); } return $this->render('AppBundle:pet:new.html.twig',array( 'entity' => $entity,'form' => $form->createView(),)); } private function createCreateForm(Pet $entity) { $form = $this->createForm(new PetType(),$entity,array( 'action' => $this->generateUrl('pet_create'),'method' => 'POST',)); return $form; } 这两个是控制器中与Pet实体对应的标准Symfony2 CRUD生成的操作. 唯一的调整是在第一个动作中插入的foreach结构,这样您就可以强制将相同的宠物添加到您在表单中选择的每个客户,从而获得所需的行为. 看,很有可能这不是正确的方式,或者是正确的方式,但是是一种方式而且它有效.希望能帮助到你. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |