Here is the situation:
I have an entity Property
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;
}
}
And the entity PropertyEquipment:
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;
}
}
The form PropertyCreation
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
));
}
}
Here is the form PropertyEquipmentCreation:
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,
]);
}
}
And the controller
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()]);
}
My error:
Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Property#$propertyEquipments", got "Doctrine\Common\Collections\ArrayCollection" instead.
Must I transform these with something like class PropertyEquipmentTransformer implements DataTransformerInterface
?
Try using Doctrine ArrayCollection instead of ArrayCollections:
This should work!
I think you should use
getParent()
function inPropertyEquipmentCreation
and inherit fromEntityType::class
then put all your field configs in theconfigureOptions()
function (remove thebuildForm
function) and it should work.You are having this problem because it is a
compound form
in your implementation and nosimple form
and symfony is unable to resolve which field created inside the subform needs to be used as source for the entity fieldFirst !
Big thanks to Nickolaus !
Here is the solution (PropertyEquipmentCreation):
And for (PropertyCreation)
Many thanks !