24

Can anyone please show me a specific example of a Symfony2 form entity update? The book only shows how to create a new entity. I need an example of how to update an existing entity where I initially pass the id of the entity on the query string.

I'm having trouble understanding how to access the form again in the code that checks for a post without re-creating the form.

And if I do recreate the form, it means I have to also query for the entity again, which doesn't seem to make much sense.

Here is what I currently have but it doesn't work because it overwrites the entity when the form gets posted.

public function updateAction($id)
{
    $em = $this->getDoctrine()->getEntityManager();
    $testimonial = $em->getRepository('MyBundle:Testimonial')->find($id);
    $form = $this->createForm(new TestimonialType(), $testimonial);

    $request = $this->get('request');
    if ($request->getMethod() == 'POST') {
        $form->bindRequest($request);

        echo $testimonial->getName();

        if ($form->isValid()) {
            // perform some action, such as save the object to the database
            //$testimonial = $form->getData();
            echo 'testimonial: ';
            echo var_dump($testimonial);
            $em->persist($testimonial);
            $em->flush();

            return $this->redirect($this->generateUrl('MyBundle_list_testimonials'));
        }
    }

    return $this->render('MyBundle:Testimonial:update.html.twig', array(
        'form' => $form->createView()
    ));
}
random
  • 9,774
  • 10
  • 66
  • 83
Jeremy Hicks
  • 3,690
  • 5
  • 40
  • 52
  • 1
    This looks similar to the code I use for editing existing entities. Can you be a little more clear about your problem? I'm unclear about what you mean by '... doesn't work because it overwrites the entity...' – Problematic Jul 07 '11 at 20:50
  • The second line in the function that grabs the testimonial tries to do a lookup based on the $id passed in. It doesn't find one when the POST occurs and so returns null for $testimonial. I just tried changing my code to look for the hidden field in my form named 'id' when the post occurs. That seemed to get me a little further but then it complained about id in my entity being private and suggested that I create a setId() method in my entity. Apparently the console didn't create one for me for some reason. – Jeremy Hicks Jul 07 '11 at 21:06
  • Got it working. See update in post above. – Jeremy Hicks Jul 07 '11 at 21:10
  • 1
    Jeremy, would you mind putting your "update" section in a new answer and accept this. Then this question won't be listed under unanswered :-) – Manne W Aug 01 '11 at 06:47

3 Answers3

16

Working now. Had to tweak a few things:

public function updateAction($id)
{
    $request = $this->get('request');

    if (is_null($id)) {
        $postData = $request->get('testimonial');
        $id = $postData['id'];
    }

    $em = $this->getDoctrine()->getEntityManager();
    $testimonial = $em->getRepository('MyBundle:Testimonial')->find($id);
    $form = $this->createForm(new TestimonialType(), $testimonial);

    if ($request->getMethod() == 'POST') {
        $form->bindRequest($request);

        if ($form->isValid()) {
            // perform some action, such as save the object to the database
            $em->flush();

            return $this->redirect($this->generateUrl('MyBundle_list_testimonials'));
        }
    }

    return $this->render('MyBundle:Testimonial:update.html.twig', array(
        'form' => $form->createView()
    ));
}
Jeremy Hicks
  • 3,690
  • 5
  • 40
  • 52
10

This is actually a native function of Symfony 2 :

You can generate automatically a CRUD controller from the command line (via doctrine:generate:crud) and the reuse the generated code.

Documentation here : http://symfony.com/doc/current/bundles/SensioGeneratorBundle/commands/generate_doctrine_crud.html

adurieux
  • 131
  • 3
1

A quick look at the auto-generated CRUD code by the Symfony's command generate:doctrine:crudshows the following source code for the edit action

/**
     * Displays a form to edit an existing product entity.
     *
     * @Route("/{id}/edit", name="product_edit")
     * @Method({"GET", "POST"})
     */
    public function editAction(Request $request, Product $product)
    {
        $editForm = $this->createForm('AppBundle\Form\ProductType', $product);
        $editForm->handleRequest($request);
        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $this->getDoctrine()->getManager()->flush();
            return $this->redirectToRoute('product_edit', array('id' => $product->getId()));
        }
        return $this->render('product/edit.html.twig', array(
            'product' => $product,
            'edit_form' => $editForm->createView(),
        ));
    }

Note that a Doctrine entity is passed to the action instead of an id (string or integer). This will make an implicit parameter conversion and saves you from manually fetching the corresponding entity with the given id.

It is mentioned as best practice in the Symfony's documentation

medunes
  • 541
  • 3
  • 16