Symfony2 FOSRestBundle PUT Action FORM returns empty results

Dimitris Romeo Havlidis picture Dimitris Romeo Havlidis · Jun 7, 2013 · Viewed 9.8k times · Source

I am using Symfony 2.2 and the latest version of FOSRestBundle. So I have manage to make most of the actions work but I seem to have an issue with the FormBuilder that I am passing the Request of my PUT call in.

I have checked the request object and it comes from my Backbone.je model as it should (.save()) But after binding to the form the entity comes back with only the id which causes flush() to throw an error since required fields are not filled.

The action in the Controller:

header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS ');
header('Allow GET, POST, PUT, DELETE, OPTIONS ');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type, *');

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\Rest\Util\Codes;
use Symfony\Component\HttpFoundation\Request;
use Greenthumbed\ApiBundle\Entity\Container;
use Greenthumbed\ApiBundle\Form\ContainerType;

class ContainerController extends FOSRestController implements ClassResourceInterface
{
/**
 * Put action
 * @var Request $request
 * @var integer $id Id of the entity
 * @return View|array
 */
public function putAction(Request $request, $id)
{
    $entity = $this->getEntity($id);
    $form = $this->createForm(new ContainerType(), $entity);
    $form->bind($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();

        return $this->view(null, Codes::HTTP_NO_CONTENT);
    }

    return array(
        'form' => $form,
    );
}

/**
 * Get entity instance
 * @var integer $id Id of the entity
 * @return Container
 */
protected function getEntity($id)
{
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('GreenthumbedApiBundle:Container')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find Container entity');
    }

    return $entity;
}

The Form that is called:

namespace Greenthumbed\ApiBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class ContainerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('description')
            ->add('isVisible')
            ->add('type')
            ->add('size')
            ->add('creationDate')
            ->add('userId')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Greenthumbed\ApiBundle\Entity\Container',
            'csrf_protection' => false,
        ));
    }

    public function getName()
    {
        return 'greenthumbed_apibundle_containertype';
    }
}

I have tried everything so far but I am fairly new with Symfony and I cannot understand why the $entity does not contain the values received by the request.

FYI: I have tried doing it manually as in instantiating a Container class with the ID of the request and putting use the setters to input values into it and it works just fine, I just want to do things the right way as Symfony suggests it should be done.

Thank you very much in advance.

Answer

ebonhand picture ebonhand · Jul 23, 2013

Try changing the following line in putAction:

$form = $this->createForm(new ContainerType(), $entity);

to:

$form = $this->createForm(new ContainerType(), $entity, array('method' => 'PUT'));