Home » Php » php – Symfony form collection

php – Symfony form collection

Posted by: admin July 12, 2020 Leave a comment

Questions:

I’m trying to add a formType in a other form type.

CustomerType:

class CustomerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('firstname', 'text', array(
                    'required' => 'required'
                ))
                ->add('middlename')
                ->add('lastname')
                ->add('email', 'email')
                ->add('groups', 'entity', array(
                    'class' => 'MV\CMSBundle\Entity\Group',
                    'property' => 'name',
                    'query_builder' => function(EntityRepository $er) {
                        return $er->createQueryBuilder('g')
                                  ->orderBy('g.name', 'ASC');
                    }
                ))
                ->add('profile', 'collection', array(
                    'type' => new ProfileType()
                ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MV\CMSBundle\Entity\User',
        ));
    }

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

ProfileType:

class ProfileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('isActive', 'checkbox', array(
                    'required' => false
                ))
                ->add('phone')
                ->add('address')
                ->add('city')
                ->add('zipcode')
                ->add('country')
                ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MV\NameBundle\Entity\Profile',
        ));
    }

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

Then I get this message:

Expected argument of type "array or (\Traversable and \ArrayAccess)", "MV\NameBundle\Entity\Profile" given.

If I comment that line i get: (just to check what will goes wrong 😉 )

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

What do I do wrong?

Symfony2: 2.1.8-DEV

How to&Answers:

It’s not clear what your mapping is between your Customer entity and your Profile entity, but I guess there are 2 options:


Option 1: You have a OneToOne relationship (One customer can only have One profile). Therefore, you don’t need the collection at all but simply need to embed a single object.

->add('profile', new ProfileType());

Option 2: You want a ManyToOne relationship (One customer can have many profiles). In that case, you need to use to embed a collection of forms. If this is what you want, rename $profile to $profiles in your Customer entity, and do the following:

   //MV\CMSBundle\Entity\Customer  
   use Doctrine\Common\Collections\ArrayCollection;
   /**
   * Your mapping here. 
   * 
   * @ORM\ManyToOne(targetEntity="MV\NameBundle\Entity\Profile")
   */
   protected $profiles;

    public function __construct()
    {
         //This is why you had an error, this is missing from your entity
         //An object was sent instead of a collection.
         $this->profiles = new ArrayCollection();
    }

Finally, update your database.