Symfony 3.1:编辑表单创建新的数据库条目而不是更新

时间:2016-10-31 09:49:18

标签: php symfony

我在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) }}

2 个答案:

答案 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();
    }