I am trying to create a form which will collect a list of facilities and contact information:
The issue is I would like to have the facility, and exactly 4 contacts of different types. I realize I could make this work separately by making each contact a property on the Facility entity but it feels like it would be cleaner and easier to use the data later if it is in a collection.
You'll notice in the FacilityType class, I use $builder->create to add a sub-form which gives me the structure I'm expecting but I get an error when I try to persist. "A new entity was found through the relationship 'AppBundle\Entity\Facility#contacts' that was not configured to cascade persist operations for entity:...."
Thanks. My code is below.
The Facility entity:
<?php
namespace AppBundle\Form;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
class Facility
{
/**
* @ORM\Column(length=200)
*/
public $name;
/**
* @ORM\OneToMany(targetEntity="FacilityContact", mappedBy="facility")
*/
public $contacts;
public function __construct()
{
$this->contacts = new ArrayCollection;
}
}
The FacilityContact entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
class FacilityContact
{
/**
* @ORM\ManyToOne(targetEntity="facility", inversedBy="contacts")
*/
public $facility;
/**
* @ORM\Column(type="string", length=50)
*/
public $contactType;
/**
* @ORM\Column(type="string", length=200)
*/
public $name;
/**
* @ORM\Column(type="string", length=100)
*/
public $email;
/**
* @ORM\Column(type="string", length=15)
*/
public $phone;
}
Facility Form
class FacilityType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$centre = $this->centre;
$builder->add('name', 'text', array("label"=>"Facility Name");
$contacts = $builder->create("contacts", "form");
$contacts
->add("radonc", new FacilityContactType("radonc"), array("label" => "Radiation Oncologist"))
->add("physicist", new FacilityContactType("physicist"), array("label" => "Physicist Responsible"))
->add("radtherapist", new FacilityContactType("radtherapist"), array("label" => "Radiation Therapists"))
->add("datamanager", new FacilityContactType("datamanager"), array("label" => "Data manager"))
;
$builder->add($contacts);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Facility'
));
}
public function getName()
{
return 'appbundle_facility';
}
}
FacilityContact form
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class FacilityContactType extends AbstractType
{
private $contactType;
public function __construct($contactType)
{
$this->contactType = $contactType;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('contactType', 'hidden', array("read_only" => true, "data"=>$this->contactType))
->add('name', 'text', array("required" => false))
->add('phone', 'text', array("required" => false))
->add('email', 'email', array("required" => false))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\FacilityContact'
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_facilitycontact';
}
}