Symfony ManyToMany表格

时间:2015-11-12 08:05:19

标签: php symfony doctrine-orm

我有实体技能和语言,专业,平台实体与ManyToMany的关系,当我创造技能时,我选择语言,专业,平台和表格是有效的,并且正常持久和在DB中刷新。但是,当我创建语言或专业或平台时,我有错误此值无效并且在调试面板中。为什么我不明白,请帮忙:

Message Origin  Cause
This value is not valid.    skills  Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).children[skills] = [0 => AngularJS, 1 => API]

Caused by:

Symfony\Component\Form\Exception\TransformationFailedException
Unable to reverse value for property path "skills": Could not find all matching choices for the given values

Caused by:

Symfony\Component\Form\Exception\TransformationFailedException
Could not find all matching choices for the given values

在我删除的实体中

/**
 * Constructor
 */
public function __construct()
{
    $this->language = new \Doctrine\Common\Collections\ArrayCollection();
    $this->platforms = new \Doctrine\Common\Collections\ArrayCollection();
    $this->specialities = new \Doctrine\Common\Collections\ArrayCollection();
}

并且语言,专业,平台也被删除

实体:

class Skill
{
use Timestampable;
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var \MyBundle\Entity\CodeDirectoryProgramLanguages
 *
 * @ORM\ManyToMany(targetEntity="CodeDirectoryProgramLanguages", inversedBy="skills", cascade={"persist"})
 */
protected $language;

/**
 * @var \MyBundle\Entity\CodeDirectoryPlatforms
 *
 * @ORM\ManyToMany(targetEntity="CodeDirectoryPlatforms", inversedBy="skills", cascade={"persist"})
 */
protected $platforms;

/**
 * @var \MyBundle\Entity\CodeDirectorySpecialities
 *
 * @ORM\ManyToMany(targetEntity="CodeDirectorySpecialities", inversedBy="skills", cascade={"persist"})
 */
protected $specialities;

和一个例子:

class CodeDirectorySpecialities
{
use Timestampable;
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="specialities", type="string", length=255)
 */
private $specialities;

/**
 * @ORM\ManyToMany(targetEntity="MyBundle\Entity\Skill", mappedBy="specialities", cascade={"persist"})
 */
protected $skills;

并添加到所有实体

    public function __toString()
{
    return $this->string_filed_entity;
}

这是我的表格

    public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('specialities');

            $builder->add('skills','entity',
                array(
                    'class'=>'MyBundle\Entity\Skill',
                    'property'=>'skill',
                    'multiple'=>true,
                    'expanded' => true,
                )
            );
}

和行动

        $entity = new CodeDirectorySpecialities();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();

            $skills = $entity->getSkills()->getValues();
        if(!empty($skills)){
            foreach($skills as $skill){
                $skill->addSpeciality($entity);
                $em->persist($skill);
            }
        }

        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('specialities_show', array('id' => $entity->getId())));
    }

1 个答案:

答案 0 :(得分:0)

It's because the html5 validator is blocking you in your forms of specialities, platforms and languages.

To add a specialities, you don't need a skill so you've to ad to your builder :

    public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('specialities')
        ->add('skills', , 'entity', array(
            'class' => 'AppBundle\Entity\Skill',
            'property' => 'skill',
            'multiple' => true,
            'expanded' => true
          ))
    ;
}

And do the same for your 2 others 'sub forms'

If you want select one or more skills when you're creating a speciality, you just have to do in your controller :

$entity = new CodeDirectorySpecialities();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);

if ($form->isValid()) {
    $em = $this->getDoctrine()->getManager();

    $entity = $form->getData();
    $em->persist($entity);
    $em->flush();

    return $this->redirect($this->generateUrl('specialities_show', array('id' => $entity->getId())));
}

Due to your Many to many relation between both, skill will be automatically updated