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

问题描述 投票:0回答:2

我在 symfony 中更新包含两个实体(“事件”和“信息”)的表单时遇到问题。在用户尝试更新信息之前一切都工作正常。当他们这样做时,所有信息都会保存为新的数据库条目。

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->get('event') 中找到的事件实体中,但缺少 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) }}
php symfony
2个回答
1
投票

如果事件实体是您要更新的实体并且由学说管理(已加载),则需要将事件实体传递到您的表单。试试这个:

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

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();
    }
© www.soinside.com 2019 - 2024. All rights reserved.