问题
I have 3 form types (SearchForm - SearchField - SearchFieldType), each one including next like this:
SearchFormType:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class SearchFormType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('fields', 'collection', array('type' => new SearchFieldType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false))
->add('submit', 'submit', array('label' => "Buscar"))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SearchForm',
'allow_extra_fields' => true,
'csrf_protection' => false,
'validation_groups' => false,
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_searchform';
}
}
SearchFieldType:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class SearchFieldType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'hidden')
->add('slug', 'hidden')
->add('value')
->add('choices')
->add('type', new SearchFieldTypeType())
->add('actionFilter')
->add('actionHighlight')
->add('actionShow')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SearchField'
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_searchfield';
}
}
SearchFieldTypeType:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use AppBundle\Entity\SearchOperator;
class SearchFieldTypeType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$entity = $builder->getData();
$builder
->add('name', 'hidden')
->add('operators', 'entity', array('class' => 'AppBundle:SearchOperator',
'multiple' => false,
'expanded' => false))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SearchFieldType'
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_searchfieldtype';
}
}
The form renders properly, but when I submit and try to do $form->handleRequest($request) I get an exception:
Neither the property "operators" nor one of the methods "addOperator()"/"removeOperator()", "setOperators()", "operators()", "__set()" or "__call()" exist and have public access in class "AppBundle\Entity\SearchFieldType"
That's not true actually, as those methods exist and work correctly:
AppBundle\Entity\SearchFieldType:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\SearchOperator;
/**
* SearchField
*
* @ORM\Table()
* @ORM\Entity
*/
class SearchFieldType
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=100, nullable=true)
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="SearchOperator", cascade={"persist", "remove"})
* @ORM\JoinTable(
* joinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="operator_id", referencedColumnName="id")}
* )
**/
private $operators;
/**
* Constructor
*/
public function __construct()
{
$this->operators = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return SearchFieldType
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Add operator
*
* @param SearchOperator $operator
*
* @return SearchFieldType
*/
public function addOperator(SearchOperator $operator)
{
$this->operators[] = $operator;
return $this;
}
/**
* Remove operator
*
* @param SearchOperator $operator
*/
public function removeOperator(SearchOperator $operator)
{
$this->operators->removeElement($operator);
}
/**
* Get operator
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getOperators()
{
return $this->operators;
}
public function __toString()
{
return $this->name;
}
}
Stack trace:
in vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php at line 460 +
at PropertyAccessor ->writeProperty (object(SearchFieldType), 'operators', object(SearchOperator))
in vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php at line 104 +
at PropertyAccessor ->setValue (object(SearchFieldType), object(PropertyPath), object(SearchOperator))
in vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/DataMapper/PropertyPathMapper.php at line 93 +
at PropertyPathMapper ->mapFormsToData (object(RecursiveIteratorIterator), object(SearchFieldType))
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 633 +
at Form ->submit (array('operators' => '156', 'name' => 'string'), true)
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 577 +
at Form ->submit (array('type' => array('operators' => '156', 'name' => 'string'), 'value' => 'felipe', 'name' => 'Nombre', 'slug' => 'nombre'), true)
in vendor/symfony/symfony/src/Symfony/Component/Form/Form.php at line 577
EDIT:
Controller Code :
$searchFormEntity = new SearchForm();
$searchFormWithValues = $this->createForm(new SearchFormType(), $searchFormEntity, array(
'action' => $this->generateUrl('candidato'),
'method' => 'POST'
));
$searchFormWithValues->add('submit', 'submit', array('label' => 'Buscar'));
$searchFormWithValues->handleRequest($request);
回答1:
Well you have a ManyToMany relation, so it would make sense to have the operators field be a collection. However you defined it as an entity, so now the form expects to have the setOperators and getOperators methods as entity implies a ManyToOne or OneToOne relationship.
I think you need to change the statement in the class SearchFieldTypeType where adding the operators attribute to be the same as what you did before for fields in SearchFormType if you want to keep the ManyToMany relationship.
来源:https://stackoverflow.com/questions/34136594/symfony-unable-to-handle-request-in-form