【问题标题】:Symfony CollectionType self referencingSymfony CollectionType 自引用
【发布时间】:2016-09-26 07:45:47
【问题描述】:

我的实体中有多对多关联,我想使用 symfony 中的集合类型字段进行多次添加。 我以前从来没有这样做过,我有点迷路了。 我想多次拥有的字段是总部,每个总部都有一个非映射字段。 我得到的错误;

“AppBundle\Entity\SurveyManager”类中的属性“headquarter” 可以使用“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
        ]);
    }
}

更新:

这是从所有不必要的数据中剥离出来的 Entity 类

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

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

【问题讨论】:

  • 不清楚您要归档什么。请提供总部、SurveyManager、Controller的定义。并解释它是什么意思 - “我想多次拥有的字段是总部,每个总部都有一个非映射字段。”。总部没有映射到总部?这里没有错字?

标签: php symfony


【解决方案1】:

我不太明白你要存档什么,具体是什么意思:

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

但是这个错误是不言自明的。你的SurveyManager 类必须有一些方法来填充表单中的数据。流程如下 - 表单通过总部数组获取数据(例如,来自用户)。然后 Form 寻找将这个数组传递给对象的方法 - 并没有找到它们,因为您没有适当的方法。

如果属性被映射(我相信,你的意思是映射到 Doctrine),Id 无关紧要,它仍然提供了一种将数据从 Form 传递到 Object 的方法。

【讨论】:

  • 如果您查看第二个表单类,我有一个映射 => false 的字段,这就是我所说的我希望每个总部都拥有它的字段。表单中的数据映射到实体。而且我在实体中有适当的方法,这很奇怪,因为我不应该有那个错误。我将用实体更新问题
  • 我认为问题是因为我将总部以 furat 形式定义为 colection,而在 colection 形式中定义为 tren。而不是获取 Array 表单集合,而是作为 Object 实例获取
  • 不,问题不在于它。 ArrayCollection 工作得很好。而且你不映射 HeadquarterType 中的某些字段也没关系。在SurveyOptionType 中,headquarter 选项已映射,而您没有适当的方法,仅此而已。检查您的代码两次,或者直接显示。
  • 我在主要问题中添加了来自控制器的代码
  • 我已经用一个要点更新了我的问题,您可以在其中看到相同的文件,但在另一个项目中做了,所以我可以更快地修改和测试。此外,您还会发现完整的堆栈跟踪。
【解决方案2】:

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

除此之外,我在您的代码中看到的唯一问题是HeadQuarterType 中的“data_class”选项应该是HeadQuarterManager::class

【讨论】:

  • 正常情况下是的,数据类应该是那个,但我没有将数据写入该实体,我只从该实体中选择数据并将其添加到多对多关联中跨度>
  • 在我的情况下,当您将数据添加到调查管理器时,通常会嵌入一个表单以将数据添加到另一个实体。但就我而言,我只想在总部经理和我的调查之间添加关联:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 2018-05-29
  • 1970-01-01
相关资源
最近更新 更多