【问题标题】:Symfony Form howto automaticly set parent on childSymfony Form如何在孩子上自动设置父母
【发布时间】:2015-01-21 08:30:07
【问题描述】:

在我的 formType 上,我添加了另一个子表单

    // ParentFormType
    $builder->add('children', 'collection', array(
        'type' => new ChildFormType(),
        'prototype'    => true,
        'allow_delete' => true,
        'allow_add' => true,
    ));

    // ChildFormType
    $builder->add('age', 'text', array(
        'required' => true));

当我尝试将表单保存为 foreach 子级并设置父级时,有没有办法避免这种 foreach

    $em = $this->get('doctrine.orm.entity_manager');
    /** This foreach I want to avoid */
    foreach ($parent->getChildren() as $child) {
        $child->setParent($parent);
    }
    $em->persist($parent);
    $em->flush();

这是来自 Parent 的 ORM-XML:

    <one-to-many field="children" target-entity="Client\Bundle\WebsiteBundle\Entity\Children" mapped-by="parent">
        <cascade>
            <cascade-persist />
        </cascade>
    </one-to-many>

这是来自 Parent 的 ORM-XML:

    <many-to-one field="parent" target-entity="Client\Bundle\WebsiteBundle\Entity\Parent" inversed-by="children">
        <join-columns>
            <join-column name="idParents" referenced-column-name="id" on-delete="CASCADE" nullable="false" />
        </join-columns>
    </many-to-one>

【问题讨论】:

    标签: php symfony doctrine-orm doctrine


    【解决方案1】:

    除了Koalabaerchen的回答,为了让handleRequest调用父实体的addChild方法,你应该设置by_reference为false(见documentation):

    // ParentFormType
    $builder->add('children', 'collection', array(
        ...
        'by_reference' => false,
    ));
    

    【讨论】:

      【解决方案2】:

      在父实体的设置器中,您可以执行类似的操作

       public function addChild(Child $children)
          {
              $this->children->add($children);
              $children->setParent($this);
      
              return $this;
          }
      

      现在,每次您向实体添加子对象(集合中发生这种情况)时,它也会在子对象中设置父对象。

      【讨论】:

      • 我确实尝试过,但 addChild 似乎没有被 symfony 调用形式的奇怪行为。
      • 表单没有调用它。您应该手动调用它或通过 EntityManager 刷新实体
      • 这是我想避免在控制器中手动执行的操作。
      • 你必须把你的东西保存在某个地方。 CRUD 函数应该在 cronrollers 中。如果你通过handlerequest,你可以避免foreach。在上面的链接中,如果您只是持久化实体,它将被写入数据库。甚至对孩子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-05
      • 2018-09-22
      • 1970-01-01
      • 2013-04-15
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多