Search code examples
apirestsymfonyfosrestbundle

FOSRestBundle post many to one relation


I would like to know how to properly post data when Entity has another ManyToOne relation in FOSRestBundle.

User entity has locale (locale_id):

/**
 * @ORM\ManyToOne(targetEntity="Locale")
 * @ORM\JoinColumn(name="locale_id", referencedColumnName="id")
 */
private $locale;

I was hoping that passing something like:

{

    "user":{
        "firstName":"John",
        "emailAddress":"somewhere@somehow.com",
        "lastName":"Doe",
        "sex":"1",
        "locale":{
            "id":"1"
        }
    }

}

will work, but it does not pass the validation and Symfony throws:

{"code":400,"message":"Validation Failed","errors":{"children":{"firstName":[],"lastName":[],"emailAddress":[],"sex":[],"locale":{"errors":["This value is not valid."]}}}}

As you can see, locale is still wrong.

Does anyone know how can I post it properly?

EDIT

Here is how the form looks like:

<?php

namespace Software\Bundle\Form\Type;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;

/**
 * Class UserType
 * @package Software\Bundle\Form\Type
 */
class UserType extends AbstractFormType
{
    public function buildForm(FormBuilderInterface $builder, array $option)
    {
        $builder
            ->add('firstName', 'text', [
                'label' => 'word.first_name',
                'required' => true
            ])
            ->add('lastName', 'text', [
                'label' => 'word.last_name',
                'required' => true
            ])
            ->add('emailAddress', 'email', [
                'label' => 'word.email_address',
                'required' => true
            ])
            ->add('sex', 'choice', [
                'label' => 'word.sex',
                'choices' => [
                    '0' => 'word.male',
                    '1' => 'word.female'
                ],
                'required'    => true,
                'empty_value' => 'word.select',
                'empty_data' => null
            ])
            ->add('locale', 'entity', [
                'label' => 'word.locale',
                'required'    => false,
                'property' => 'code',
                'class' => 'SoftwareBundle:Locale',
                'query_builder' => function(EntityRepository $er) {
                        return $er->createQueryBuilder('l')
                            ->orderBy('l.code', 'ASC');
                    },
                'placeholder' => 'word.select',
                'empty_data'  => null
            ])
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'translation_domain'    => 'general',
            'data_class'            => 'Software\Bundle\Entity\User',
            'attr'                  => ['novalidate' => 'novalidate'],
            'csrf_protection'       => false
        ]);
    }

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

EDIT 2

And the controller:

public function postAction(Request $request)
{
    $form = $this->createForm(new UserType(), new User());
    $form->handleRequest($request);

    if($form->isValid())
    {
        die('are you valid or not??');
    }

    return $this->view($form, 400);
}

Solution

  • Try without the "1" and only with 1 , otherwise it can be interpreted as string.

    Edit :

    {
    
        "user":{
            "firstName":"John",
            "emailAddress":"somewhere@somehow.com",
            "lastName":"Doe",
            "sex":"1",
            "locale": 1
            }
        }
    
    }