0

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.

TroyashkA
  • 49
  • 3
  • 9

2 Answers2

2

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.

Nicolai Fröhlich
  • 51,330
  • 11
  • 126
  • 130
  • Thank you for your support for all my questions today :) – TroyashkA Jul 18 '13 at 15:53
  • p.s. and one moment. So I must create a setter for id? I don't know why symfony can't auto-generate setter for ID field – TroyashkA Jul 18 '13 at 16:04
  • http://stackoverflow.com/questions/17089307/how-do-i-configure-a-doctrine2-entity-which-extends-persistentobject-within-symf ... See my answer over here on how to use Doctrine's PersistentObject if you don't want to create getters and setters for your entities but i don't recommend it. with IDE integration (Eclipse PDT Extras, Sublime via Plugin, PHPStorm all have auto-generation methods ) or `doctrine:generate:entities` command it's really just a matter of seconds to generate some getters/setters. – Nicolai Fröhlich Jul 18 '13 at 16:39
1

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.

Martin Lyne
  • 3,157
  • 2
  • 22
  • 28