Symfony CollectionType自引用

时间:2016-09-26 07:45:47

标签: php symfony

我的实体中有多对多的关联,我想使用symfony中的集合类型字段多次添加。 我之前从未这样做过,我有点失落。 我希望多次访问的领域是总部,每个总部都有一个非映射字段。 我得到的错误;

  

该物业"总部"在课堂上#34; AppBundle \ Entity \ SurveyManager"   可以用方法定义" addHeadquarter()",   " removeHeadquarter()"但新值必须是数组或   \ Traversable的实例," AppBundle \ Entity \ HeadQuarterManager"给出。

实施集合的表单类型。

class SurveyOptionType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('headquarter', CollectionType::class, [
                'entry_type' => HeadQuarterType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'label' => 'Sediu',
            ])
            ->add('isEnabled', CheckboxType::class, [
                'label' => 'Chestionar Activ',
                'required' => false,
            ])
            ->add('submit', SubmitType::class, [
                'label' => 'Salveaza',
            ]);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => SurveyManager::class
        ]);
    }
}

这是收集表格

class HeadQuarterType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('headquarter', EntityType::class, [
                'class' => HeadQuarterManager::class,
                'label' => 'Sediu',
            ])
            ->add('userNumber', TextType::class, [
                'label' => 'Numar Utilizatori',
                'mapped' => false,
            ])
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => SurveyManager::class
        ]);
    }
}

更新:

这是从所有不确定数据中删除的实体类

class SurveyManager
{

    /**
     * @var int
     *
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\HeadQuarterManager")
     * @ORM\JoinTable(name="survey_headquarters",
     *      joinColumns={@ORM\JoinColumn(name="survey_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="headquarter_id", referencedColumnName="id")}
     *      )
     */
    private $headquarter;

    public function __toString()
    {
        // TODO: Implement __toString() method.
        return $this->name;
    }


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



    /**
     * Add headquarter
     *
     * @param \AppBundle\Entity\HeadQuarterManager $headquarter
     *
     * @return SurveyManager
     */
    public function addHeadquarter(\AppBundle\Entity\HeadQuarterManager $headquarter)
    {
        $this->headquarter[] = $headquarter;

        return $this;
    }

    /**
     * Remove headquarter
     *
     * @param \AppBundle\Entity\HeadQuarterManager $headquarter
     */
    public function removeHeadquarter(\AppBundle\Entity\HeadQuarterManager $headquarter)
    {
        $this->headquarter->removeElement($headquarter);
    }

    /**
     * Get headquarter
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getHeadquarter()
    {
        return $this->headquarter;
    }
}

控制器方法

$em = $this->getDoctrine()->getManager();
$surveyRepository = $em->getRepository(SurveyManager::class);
//$surveyManager = $surveyRepository->findOneById($surveyId);
$surveyManager = new SurveyManager();
$form = $this->createForm(SurveyOptionType::class, $surveyManager);
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
    $em = $this->getDoctrine()->getManager();
    $em->persist($surveyManager);
    $em->flush();

    return $this->redirectToRoute('admin_survey-manager_survey_options',
        [
            'id' => $surveyManager->getId()
        ]);
}

return [
    'surveyManager' => $surveyManager,
    'form' => $form->createView(),
];

在做这方面的研究时,我做了一个单独的演示来测试它以更好地解决问题。

这是一个简化的更新代码,应该可以正常工作

https://gist.github.com/bogdaniel/a0bcc848e2bd282382f45a2bd15cc0e2

您可以在要点中找到有关错误的更多信息。

2 个答案:

答案 0 :(得分:0)

我真的不明白你想要存档什么,以及它究竟意味着什么:

  

我想多次访问的领域是总部,每个总部都有一个非映射字段。

但错误是非常自我解释的。您的SurveyManager类必须有一些方法来填充Form中的数据。流程如下 - 表单从总部阵列获取数据(例如来自用户)。然后Form查找将此数组传递给对象的方法 - 并且由于您没有适当的方法而无法找到它们。

如果属性被映射(我认为,你的意思是映射到Doctrine),ID并不重要,它仍然提供了一种将数据从Form传递给Object的方法。

答案 1 :(得分:0)

你是如何呈现表格的?我怀疑类似于此处发现的问题:Error : the new value must be an array or an instance of \Traversable, Entity class given

除此之外,我在代码中看到的唯一问题是来自HeadQuarterType的'data_class'选项应为HeadQuarterManager::class