Skip to content
Advertisement

Symfony Form EntityType doesn’t select the current value on render by default

I stumbled upon an odd behavior and I’m still not sure if my solution is the most appropriate one, even though it works now.

I have 2 entities:

class Recipe
{
    /** [...] */
    public $id;

    /** @ORMColumn(type="string", length=255) */
    public $name;

    /** @ORMManyToOne(targetEntity="AppEntityLocation") */
    public $location;
}

class Location
{
    /** [...] */
    public $id;

    /** @ORMColumn(type="string", length=255) */
    public $name;

    /** @ORMOneToMany(targetEntity="AppEntityRecipe", mappedBy="location") */
    protected $recipes;
}

Nothing fancy here. A location can hold several recipes, and a recipe can be in one location at most.

The recipe form is built as follows:

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add(
                'name',
                TextType::class,
                ['label' => 'Name',]
            )
            ->add(
                'location',
                EntityType::class,
                [
                    'label' => 'Location',
                    'class' => AppEntityLocation::class,
                    'choice_value' => function ($location) {
                        // Why is this code necessary?
                        return is_object($location)
                            ? $location->getId()    // Object passed (when building choices)
                            : $location;            // int value passed (when checking for selection)
                    },
                    'choice_label' => 'name',
                ]
            )
        ;
    }

Then the controller creates the form and so on.

    /**
     * @ParamConverter("entity", class="App:Recipe", isOptional="true")
     */
    public function edit(Request $request, object $entity = null) {
        $form = $this->createForm(AppFormRecipe::class, $entity ?? new Recipe());
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            // ...
        }
        // ...
    }

My original implementation didn’t have the choice_value callback above on the EntityType form element, and the option was never selected when I opened an existing location. But apart from that, everything was working as expected and selecting a value did save it correctly in the database, without more code but Symfony’s magic.

Could you tell me why this choice_value is necessary here? Did I miss something? Why is the value passed as argument is sometimes an object, and sometimes an integer?

Advertisement

Answer

Oh… Found it. Actually I had an old DataTransformer that was associated to this field and it was messing with the values. I didn’t need it anymore anyway so just removing it magically fixed the bug.

Thanks for your help anyway, it did confirm that something wasn’t right and forced me to dig deeper.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement