TroyashkA
TroyashkA

Reputation: 49

Proper way to update class object in db using symfony2 + doctrine + form?

I have a simple class:

class Type
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=15)
     */
    private $name;

    ... 
}

And have a some 'type' objects in database. So, if i want to change one of them, i create new controller rule (like /types/edit/{id}) and new action:

public function typesEditViewAction($id)
{   
    ... 
    $editedType = new Type();

    $form = $this->createFormBuilder($editedType)
        ->add('name', 'text')
        ->add('id', 'hidden', array('data' => $id))
        ->getForm();

    // send form to twig template
    ...
}

After that, i create another controller rule (like /types/do_edit) and action:

public function typesEditAction(Request $request)
{   
    ... 
    $editedType = new Type();

    $form = $this->createFormBuilder($editedType)
        ->add('name', 'text')
        ->add('id', 'hidden')
        ->getForm();

    $form->bind($request); // <--- ERROR THERE !!!

    // change 'type' object in db
    ...
}

And i found a small problem there. Сlass 'Type' doesn't have аuto-generated setter setId() and on binding i got error.

Neither the property "id" nor one of the methods "setId()", "__set()" or "__call()" exist and have public access in class "Lan\CsmBundle\Entity\Type".

Now, i remove 'id' field from symfony2 form object ($form) and transmit it manually to template. At second controller's action i have $form object and 'id'-field apart. I don't know a 'proper'-way for doing that (updating 'type' class). Please help.

Upvotes: 0

Views: 4154

Answers (2)

Martin Lyne
Martin Lyne

Reputation: 3065

For anyone else stumbling on this where you added the ID field to your FormType because the frontend needed it you can just set the ID column to "not-mapped" like so:

->add('my_field', 'hidden', ['mapped'=>false])

and it prevents the ID value trying to get used by the form processing method.

Upvotes: 1

Nicolai Fr&#246;hlich
Nicolai Fr&#246;hlich

Reputation: 52493

Symfony has an integrated ParamConverter which automatically fetches your entity from database and throws an Exception ( which you can catch in a listener ) if the entity is not found.

You can easily handle GET and POST requests in one controller method.

make sure you have the public getters and setters for your properties in your entity.

I added annotations to make the routing clearer and still have a working example.

use Vendor\YourBundle\Entity\Type;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

// ...

/** 
 *  @Route("/edit/{id}", requirements={"id" = "\d+"})
 *  @Method({"GET", "POST"})
 */
public function editAction(Request $request, Type $type)
{   

    $form = $this->createFormBuilder($type)
        ->add('name', 'text')
        ->add('id', 'hidden')
        ->getForm()
    ;

    if ($request->isMethod('POST')) {
         $form->bind($request);

         if ($form->isValid())
         {
              $em = $this->getDoctrine()->getEntityManager();
              $em->flush();          // entity is already persisted and managed by doctrine.

              // return success response
         }
    }

    // return the form ( will include the errors if validation failed )
}

I strongly suggest you should create a form type to further simplify your controller.

Upvotes: 2

Related Questions