Symfony 5:创建Bordereau时生成关联BordereauStagiaire实体的方法
问题:如何在创建Bordereau的同时生成关联的BordereauStagiaire?
我拥有三个实体:Bordereau、Stagiaire、BordereauStagiaire,通过多步骤表单创建新的Bordereau,需要向用户展示选中的Stagiaire并完成验证,Bordereau与Stagiaire通过BordereauStagiaire表关联。
已在控制器中通过表单获取到两者的ID,希望在创建Bordereau的同时创建对应的BordereauStagiaire,实现思路是先创建Bordereau,再用其ID和选中的Stagiaire创建包含amount属性的BordereauStagiaire。请问如何利用从表单获取的Bordereau ID和Stagiaire ID创建新的BordereauStagiaire?
原控制器代码:
#[Route('/create/bordereau', name: 'app_bordereau_create', methods: ['GET','POST'])] public function createBordereauAction(CreateBordereauFlow $flow, PersistenceManagerRegistry $doctrine) { $formBordereau = new Bordereau(); $formBordStag = new BordereauStagiaire(); $formBordereau->setUser($this->getUser()); $flow->bind($formBordereau); $form = $flow->createForm(); if ($flow->isValid($form)) { $flow->getCurrentStepNumber($form); $flow->saveCurrentStepData($form); if ($flow->nextStep()) { $form = $flow->createForm(); $flow->getCurrentStepNumber($form); $flow->saveCurrentStepData($form); // dd($form['stagiaire']->getData()[0]->getId()); // dd($form->getData()); } else{ $entityManager = $doctrine->getManager(); $entityManager->persist($formBordereau); $entityManager->flush(); // dd($formBordereau->getId()); return $this->redirectToRoute('app_bordereau_index'); } } // if ($flow->redirectAfterSubmit($form)) { // // $request = $this->getRequest(); // $params = $this->formFlowUtil->addRouteParameters(array_merge($request->query->all(), // $request->attributes->get('_route_params')), $flow); // return $this->redirectToRoute($request->attributes->get('_route'), $params); // } return $this->render('bordereau/create_bordereau.html.twig', [ 'form' => $form->createView(), 'flow' => $flow, 'formBordereau' =>$formBordereau, ]); }
注:通过$form['stagiaire']->getData()[0]->getId()获取Stagiaire数据,持久化并刷新数据库后通过$formBordereau->getId()获取Bordereau的ID。
解决方案
核心思路是在Bordereau成功持久化后,实例化BordereauStagiaire并设置关联属性,最后持久化该关联实体:
- 获取选中的Stagiaire实体:直接从表单数据中获取Stagiaire实例(而非仅ID,避免额外查询数据库)
- 实例化并配置BordereauStagiaire:设置关联的Bordereau、Stagiaire,以及必填的
amount属性 - 持久化关联实体:将BordereauStagiaire加入EntityManager并刷新
修改后的控制器代码(关键部分已标注):
#[Route('/create/bordereau', name: 'app_bordereau_create', methods: ['GET','POST'])] public function createBordereauAction(CreateBordereauFlow $flow, PersistenceManagerRegistry $doctrine) { $formBordereau = new Bordereau(); $formBordereau->setUser($this->getUser()); $flow->bind($formBordereau); $form = $flow->createForm(); if ($flow->isValid($form)) { $flow->getCurrentStepNumber($form); $flow->saveCurrentStepData($form); if ($flow->nextStep()) { $form = $flow->createForm(); $flow->getCurrentStepNumber($form); $flow->saveCurrentStepData($form); } else{ $entityManager = $doctrine->getManager(); $entityManager->persist($formBordereau); $entityManager->flush(); // --- 新增:创建BordereauStagiaire关联 --- // 获取选中的Stagiaire实例(假设是单选,取第一个元素) $selectedStagiaire = $form['stagiaire']->getData()[0]; // 实例化关联实体 $bordereauStagiaire = new BordereauStagiaire(); $bordereauStagiaire->setBordereau($formBordereau); $bordereauStagiaire->setStagiaire($selectedStagiaire); $bordereauStagiaire->setAmount(100); // 替换为实际业务的amount值,可从表单获取或默认值 // 持久化关联实体 $entityManager->persist($bordereauStagiaire); $entityManager->flush(); // --- 新增结束 --- return $this->redirectToRoute('app_bordereau_index'); } } return $this->render('bordereau/create_bordereau.html.twig', [ 'form' => $form->createView(), 'flow' => $flow, 'formBordereau' =>$formBordereau, ]); }
注意事项
- 如果是多选Stagiaire,需要用循环遍历
$form['stagiaire']->getData()数组,为每个Stagiaire创建对应的BordereauStagiaire amount属性的值建议从表单中获取(如果多步骤表单包含该字段),而非硬编码- 确保实体类中已正确定义关联关系(如BordereauStagiaire中的
setBordereau、setStagiaire方法存在且正确映射)
内容的提问来源于stack exchange,提问作者Ralda00
相关产品推荐
相关产品推荐

