我在symfony中更新包含两个实体(" Event"和#34; Info)的表单时遇到问题。一切正常,直到用户尝试更新信息。当他们这样做时,所有都保存为新的数据库条目。
public function editAction(Request $request, Event $event)
{
$user = $this->getUser();
$editForm = $this->createFormBuilder()
->setMethod('PUT');
$editForm->add("event", 'AppBundle\Form\EventType');
$editForm->add("info", 'AppBundle\Form\InfoType');
$editForm = $editForm->getForm();
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$formEvent = $editForm->get('event')->getData();
echo "Debug<br />";
echo "form id: ". $formEvent->getId(); // Wrong. Returns null.
echo "<br /> event id: ". $event->getId(); // The correct id of entity that should be updated.
$em->merge($formEvent);
$em->flush();
} else {
$editForm->get('event')->setData($event);
}
return $this->render('event/edit.html.twig', array(
'event' => $event,
'edit_form' => $editForm->createView()
));
我回显一些调试信息,而handleRequest()会将新信息映射到$ editForm-&gt; get(&#39; event&#39;)中找到的事件实体,除了它的例外情况我遗漏了Id,它与创建新实体而不是更新有关。什么了?
路由:
event_edit:
path: /{id}/edit
defaults: { _controller: "AppBundle:Event:edit" }
methods: [GET, POST, PUT]
嫩枝:
{{ form_start(edit_form, {'attr': {'novalidate': 'novalidate'}}) }}
{{ form_errors(edit_form) }}
{{ form_widget(edit_form.event.title) }}
{{ form_widget(edit_form.info) }}
<input type="submit" value="Save" />
{{ form_end(edit_form) }}
答案 0 :(得分:1)
如果事件实体是您要更新的实体并且由doctrine(已加载)管理,则需要将事件实体传递给表单。试试这个:
public function editAction(Request $request, Event $event)
{
$user = $this->getUser();
$editForm = $this->createFormBuilder($event)
->setMethod('PUT');
$editForm->add("event", 'AppBundle\Form\EventType');
$editForm->add("info", 'AppBundle\Form\InfoType');
$editForm = $editForm->getForm();
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($event);
$em->flush();
}
return $this->render('event/edit.html.twig', array(
'event' => $event,
'edit_form' => $editForm->createView()
));
}
答案 1 :(得分:0)
因此,由于我在更新实体时也遇到了问题-我将把信息留给其他人。
Symfony版本: 4.3.x
$contact_form = $this->app->forms->contact()->handleRequest($request);
此代码仅返回表单,然后传递请求
public function contact(array $params = [], MyContact $my_contact_type = null): FormInterface {
return $this->createForm(MyContactType::class, $my_contact_type, $params);
}
这不会更新现有表格。您必须将实体作为数据(第二个参数)传递。
现在我又学到了另一件有趣的事情。
我的渲染视图使用 contact_form 和其他表单中的字段,因此我拥有一种从请求中提取子表单并提交它们的机制。最后,我得到了Request
的原始表单数据。
现在,如果您执行$form->getData
,则可以从请求中获得整个实体构建。我已经修改了视图,以便我也可以填写id表单,因此,我拥有数据库中已存在的100%相同的实体-1:1进行了比较。
根据请求建立这样的实体将导致创建新实体。 您必须从数据库获取实体以进行更新。
这就是我处理这种情况的方式:
public function saveEntity(MyContact $my_contact, bool $search_and_rebuild_entity = false){
if( $search_and_rebuild_entity ){
$id = $my_contact->getId();
$name = $my_contact->getName();
$contacts = $my_contact->getContacts();
$description = $my_contact->getDescription();
$image_path = $my_contact->getImagePath();
$name_background_color = $my_contact->getNameBackgroundColor();
$description_background_color = $my_contact->getDescriptionBackgroundColor();
$found_entity = $this->find($id);
if( !empty($found_entity) ){
$my_contact = $found_entity;
$my_contact->setName($name);
$my_contact->setContacts($contacts->toJson());
$my_contact->setImagePath($image_path);
$my_contact->setDescription($description);
$my_contact->setNameBackgroundColor($name_background_color);
$my_contact->setDescriptionBackgroundColor($description_background_color);
}
}
$this->_em->persist($my_contact);
$this->_em->flush();
}