How to use entities in collection (+prototype) in Symfony 2.1
-
20-06-2021 - |
Question
I want to add a collection of entities in Symfony 2.1.0-dev bug I got:
Neither property "sitterDegrees" nor method "getSitterDegrees()" nor method "isSitterDegrees()" exists in class "xxx\Entity\Degrees"
It happen because I have an entity in DegreesFormType.php and at this line
$this->form->bindRequest($request);
in my handler.
I want to add multiple "degrees" on "sitter" entity (but degrees are a choice not like http://symfony.com/doc/master/cookbook/form/form_collections.html)
Did I forget something?
Entities
A simple ManyToMany between Sitter and Degrees
Sitter
class Sitter
{
//some properties
/**
* @var xxx\Entity\Degrees
* @ORM\ManyToMany(targetEntity="xxx\Entity\Degrees", orphanRemoval=true, inversedBy="sitters",cascade={"persist"})
* @ORM\JoinTable(name="sitter_degrees_relationships",
* joinColumns={
* @ORM\JoinColumn(name="sitter_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="degrees_id", referencedColumnName="id")
* }
* )
*/
private $sitterDegrees;
public function getSitterDegrees()
{
return $this->sitterDegrees;
}
public function setSitterDegrees(ArrayCollection $sitterDegrees)
{
foreach ($sitterDegrees as $sitterDegree) {
$sitterDegree->addSitter($this);
}
$this->sitterDegrees = $sitterDegrees;
}
public function addSitterDegree(xxx\Entity\Degrees $sitterDegrees)
{
$this->sitterDegrees[] = $sitterDegrees;
return $this;
}
public function removeSitterDegree(xxx\Entity\Degrees $sitterDegrees)
{
$this->sitterDegrees->removeElement($sitterDegrees);
}
}
Degrees
class Degrees
{
public function __toString(){return $this->name;}
private $id;
private $name;
/**
* @var xxx\Entity\Sitter
* @ORM\ManyToMany(targetEntity="xxx\Entity\Sitter", mappedBy="sitterDegrees")
*/
private $sitters;
public function __construct()
{
$this->sitters = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function getSitters()
{
return $this->sitters;
}
public function addSitter(xxx\Entity\Sitter $sitter)
{
if (!$this->sitters->contains($sitter)) {
$this->sitters->add($sitter);
}
}
public function removeSitter(xxx\Entity\Sitter $sitters)
{
$this->sitters->removeElement($sitters);
}
}
FormType
VerifFormType.php is my main form, it embed DegreesFormType.
VerifFormType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//->add('some_properties')
->add('sitterDegrees', 'collection', array(
'type' => new DegreesFormType(),
'by_reference' => false,
'allow_add' => true,
'allow_delete' => true,
)
);
}
DegreesFormType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('sitterDegrees', 'entity', array(
'class' => 'xxx:Degrees'
));
}
Controller
public function indexAction()
{
$user = $this->get('security.context')->getToken()->getUser();
$sitter = $user->sitter;
$formHandler = $this->get('xxx.form.handler');
$form = $formHandler->getForm();
$form->setData($sitter);
if ($formHandler->process()) {
//ok
}
//fail
}
Handler
public function process()
{
$request = $this->container->get('request');
if ('POST' == $request->getMethod()) {
$this->form->bindRequest($request);//Fail at this line
if ($this->form->isValid()) {
return $this->onSuccess();
}
}
return false;
}
public function onSuccess()
{
$sitter = $this->form->getData();
$this->form->bindRequest($this->container->get('request'));
$sitter->setContainer($this->container);
$this->container->get('xxx.manager')->persistSitter($sitter);
return true;
}
index.html.twig
With some javascript like in the cookbook http://symfony.com/doc/master/cookbook/form/form_collections.html
<ul class="degrees" data-prototype="{{ form_widget(form.sitterDegrees.getVar('prototype')) | e }}">
{% for sitterDegree in form.sitterDegrees %}
<li>{{ form_row(sitterDegree) }}</li>
{% endfor %}
</ul>
Solution
The error comes from DegreesFormType: The sitterDegrees
field maps to a setterDegrees
property in your Degrees
class. However, this class doesn't have such property.
There is a similar problem in VerifFormType
: The sitterDegrees
field maps to a setterDegrees
property in your Sitter
class. However, this class doesn't have such property.