Symfony hiddenType using data_class for entity ins

2019-08-12 16:21发布

问题:

So i tried to store the id of one of my entities in the hiddenType and i got:

The form's view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is an instance of class AppBundle\Entity\Users. You can avoid this error by setting the "data_class" option to "AppBundle\Entity\Users" or by adding a view transformer that transforms an instance of class AppBundle\Entity\Users to scalar, array or an instance of \ArrayAccess.

data_class: "This option is used to set the appropriate data mapper to be used by the form, so you can use it for any form field type which requires an object."

see: http://symfony.com/doc/2.7/reference/forms/types/form.html#data-class

and so i fix my form:

$builder
    ->add('user', 'hidden', array(
        'data_class' => 'AppBundle\Entity\User',
    ));

when i try this i get an exception stating that my entity cannot be translated to a string

so i implement the __tostring magic method on my entity to return the entity’s id, then twig is able to put the entity id in the hidden field value

then when i try to submit my form i get:

Catchable Fatal Error: Argument 1 passed to AppBundle\Entity\Students::setUser() must be an instance of AppBundle\Entity\Users, string given, called in /vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 442 and defined

so its not able to pull the string value from the request back into an entity for use in my form.

yes, i've seen the implementation where you build a entityHiddenType using a transformer.

however i'm asking is this possible using the data_class setting provided by symphony as i believe this is the intended method to solve this?

I just want to know if it can be achieved using data_class instead of a transformer. as well as which method is best practice.

回答1:

I had the same issue, I solved it by setting the data_class to null in my for my HiddenType:

<?php namespace AppBundle\Forms\Signup;


use AppBundle\Entity\Course;
use AppBundle\Repository\CourseRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PreselectedCourseType extends AbstractType
{
    private $courseRepository;

    public function __construct(CourseRepository $courseRepository)
    {
        $this->courseRepository = $courseRepository;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $selectedCourse = $options['selected_course'];

        $builder
            ->add("course", HiddenType::class,['data' => $selectedCourse, 'data_class' => null]);


        $builder->get("course")->addModelTransformer(new CallbackTransformer(
            function (Course $course = null) {return $course? $course->getId():0;},
            function ($course = null) {return $this->courseRepository->getCourse($course);}
        ));
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => CourseDTO::class,
            'label' => false,
            'selected_course' => 0
        ]);
        $resolver->setRequired("selected_course");
    }
}