Symfony - 形式 - 多对多关系 - 集合类型

时间:2016-09-28 15:13:23

标签: php doctrine-orm many-to-many symfony

情况如下:

我有一个实体属性

实体PropertyEquipment:

class Property
{
    /**
     * @ORM\Id
     * @ORM\Column(type="string")
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="PropertyEquipment", inversedBy="properties")
     */
    protected $propertyEquipments;

    public function __construct()
    {
        $this->propertyEquipments = new ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    public function addPropertyEquipment(\AppBundle\Entity\PropertyEquipment $propertyEquipment)
    {
        $this->propertyEquipments[] = $propertyEquipment;

        return $this;
    }

    public function removePropertyEquipment(\AppBundle\Entity\PropertyEquipment $propertyEquipment)
    {
        $this->propertyEquipments->removeElement($propertyEquipment);
    }

    public function getPropertyEquipments()
    {
        return $this->propertyEquipments;
    }
}

表单PropertyCreation

class PropertyEquipment
{

    /**
     * @ORM\Id
     * @ORM\Column(type="string")
     * @ORM\GeneratedValue(strategy="UUID")
     */
    protected $id;

    /**
     * @ORM\ManyToMany(targetEntity="Property", mappedBy="propertyEquipments")
     */
    protected $properties;

    /**
     * @ORM\Column(type="string", length=100)
     * @Gedmo\Translatable
     */
    protected $equipmentName;


    public function __construct()
    {
        $this->properties = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return mixed
     */
    public function getEquipmentName()
    {
        return $this->equipmentName;
    }

    /**
     * @param mixed $equipmentName
     */
    public function setEquipmentName($equipmentName)
    {
        $this->equipmentName = $equipmentName;
    }

    public function addProperty(Property $property)
    {
        $this->properties[] = $property;

        return $this;
    }

    public function removeProperty(Property $property)
    {
        $this->properties->removeElement($property);
    }

    public function getProperties()
    {
        return $this->properties;
    }
}

以下是PropertyEquipmentCreation形式:

class PropertyCreation extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            //with this I see the values coming from DB in the template
            ->add("propertyEquipments", PropertyEquipmentCreation::class)

            //with this it's empty :/
            /*->add("propertyEquipments", CollectionType::class, array(
                "entry_type" => PropertyEquipmentCreation::class,
            ))*/
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Property::class
        ));
    }
}

和控制器

class PropertyEquipmentCreation extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder      
            ->add('propertyEquipment', EntityType::class, [
                'class' => 'AppBundle\Entity\PropertyEquipment',
                'choice_label' => 'equipmentName',
                'expanded' => true,
                'multiple' => true
            ]);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => PropertyEquipment::class,
        ]);
    }
}

我的错误:

public function createPropertyAction(Request $request) { $property = new Property(); $form = $this->createForm(PropertyCreation::class, $property); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $entityManager = $this->getDoctrine()->getManager(); $entityManager->persist($property); $entityManager->flush(); return $this->redirectToRoute('homepage'); } return $this->render('form/owner_create_property.html.twig', ["form" => $form->createView()]); }

我是否必须使用Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Property#$propertyEquipments", got "Doctrine\Common\Collections\ArrayCollection" instead.

之类的内容对其进行转换

3 个答案:

答案 0 :(得分:2)

我认为你应该在getParent()中使用PropertyEquipmentCreation函数并从EntityType::class继承,然后将所有字段配置放在configureOptions()函数中(删除buildForm功能),它应该工作。

您遇到此问题,因为它在您的实现中是compound form且没有simple form,并且symfony无法解析在子窗体内创建的字段需要用作实体字段的源< / p>

答案 1 :(得分:1)

首先!

非常感谢Nickolaus!

这是解决方案(PropertyEquipmentCreation):

namespace AppBundle\Form\Type;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;


class PropertyEquipmentCreation extends AbstractType
{

/**
 * @param OptionsResolver $resolver
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'class' => 'AppBundle\Entity\PropertyEquipment',
        'choice_label' => 'equipmentName',
        'expanded' => true,
        'multiple' => true,
    ]);
}

public function getParent()
{
    return EntityType::class;
}
}

和(PropertyCreation)

<?php


namespace AppBundle\Form;


use AppBundle\Form\Type\PropertyEquipmentCreation;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PropertyCreation extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('description', TextareaType::class)
        ->add('name', TextType::class)
        ->add("propertyEquipments", PropertyEquipmentCreation::class)
        ->add('save', SubmitType::class);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => Property::class
    ));
}
}

非常感谢!

答案 2 :(得分:0)

尝试使用Doctrine ArrayCollection而不是ArrayCollections:

$this->propertyEquipments = new \Doctrine\Common\Collections\ArrayCollection();

这应该有效!