【问题标题】:Symfony 2 form : entity widget with many to one/one to many relation - relation not persistingSymfony 2形式:具有多对一/一对多关系的实体小部件 - 关系不持久
【发布时间】:2013-03-09 23:51:29
【问题描述】:

我有一个审核表单,我可以在其中附加多个资源(审核有很多资源,一个资源仅附加到一个审核)。

表单在视图中很好地呈现,但在保存表单时,选定的资源未附加到数据库中的审核。

审核表:

>add('ressources', 'entity', array(
            'class' => 'SpriMonitorBusinessBundle:Ressource',
            'query_builder' => $this->em->getRepository('SpriMonitorBusinessBundle:Ressource')->getAvailableRessources(true),
            'multiple'=>true
    ))

审计.orm.yml:

oneToMany:
    ressources:
      targetEntity: Ressource
      mappedBy: audit

Ressource.orm.yml:

manyToOne:
    audit:
      targetEntity: Audit
      inversedBy: ressources
      joinColumn:
        name: audit_id
        referencedColumnName: id

注意:在资源表单上,当我选择审核时,它已正确保存

控制器:

public function newAction()
    {
        $em = $this->getDoctrine()->getEntityManager();
        $item = AuditFactory::make();
        $form = $this->createForm(new AuditType($em),$item);

        $request = $this->get('request');
        $session = $this->get('session');

        if ('POST' == $request->getMethod()) {
            try {

                $this->validateForm($form,$request);
                $em->persist($item);
                $em->flush();
                $message  = $this->container->getParameter('form_submit_success');
                $session->setFlash('success', $message);
                $url = $this->generateUrl('Spri_audit_list');

                return $this->redirect($url);

            } catch (FormException $e) {
                $session->setFlash('error', sprintf('Erreur Formulaire : "%s"',$e->getMessage()));
            } catch (\Exception $e) {
                die(var_dump($e->getMessage()));
                $session->setFlash('error', sprintf('Erreur inconnue !  Contactez l\'ADMIN'.$e->getMessage()));
            }
        }

        return $this->render('SpriAuditBundle:Audit:new.html.twig', array('form'=>$form->createView()));
    }

    protected function validateForm($form, $request)
    {
        $form->bind($request);
        if (!$form->isValid()) {
            $message  = $this->container->getParameter('form_submit_error');
            throw new FormException($message);
        }
    }

var_dump($item) 显示:

private 'slug' => null
  private 'ressources' => 
    object(Doctrine\Common\Collections\ArrayCollection)[4190]
      private '_elements' => 
        array
          0 => 
            object(Spri\MonitorBusinessBundle\Entity\Ressource)[3766]
              ...
  privat...

有什么想法吗??

【问题讨论】:

  • 您可以将您的控制器发布到您坚持并刷新实体管理器的位置吗?
  • 如果您在持久化之前执行 var_dump($item),它是否将资源显示为子项?
  • 我们还需要查看您的创建操作。
  • @KenHannel:请查看已编辑的问题!
  • @Lighthart:什么创建动作?

标签: php symfony orm doctrine-orm symfony-forms


【解决方案1】:

您必须通过编辑实体的addRessource() 方法手动在Ressource 实体中设置Audit 实体。

只需像这样编辑这个方法:

public function addRessource(Ressource $ressource)
{
    $this->ressources[] = $ressource;
    $ressource->setAudit($this);

    return $this;
}

UPD

然后尝试在控制器中手动持久化资源:

foreach ($audit->getRessources() as $ressource) {
    $em->persist($ressource);
}

UPD

嗯,很奇怪。执行下一段代码 sn -p 并检查 ressources 关系:

$em = $this->getDoctrine()->getManager();

$ressource = new Ressource();
$ressource->setSomeRequiredFieldValue($someValue);

$audit = new Audit();
$audit->setSomeRequiredFieldValue($someValue);
$audit->addRessource($ressource);

$em->persist($audit);
$em->persist($ressource);
$em->flush();

【讨论】:

  • 您是否在架构中审计实体的资源属性中添加了“cascade: [persist]”(不确定语法,我从不使用架构文件)?
  • 是 :oneToMany: ressources: targetEntity: Ressource mappedBy: audit cascade: ["persist", "merge"]
  • 我已经更新了我的答案。我确信级联会持续存在,并且我的答案中的第一步应该可以工作。同时尝试将 Symfony 更新到最新版本。
  • 我按照你的要求做了,但没有任何改变!
  • 我有一个 Symfony 2.2.0 版
【解决方案2】:

好吧,我想我知道发生了什么。这个更新的控制器应该可以解决您的问题:

public function newAction()
{
    $em = $this->getDoctrine()->getEntityManager();
    $item = AuditFactory::make();
    $form = $this->createForm(new AuditType($em),$item);

    $request = $this->get('request');
    $session = $this->get('session');

    if ('POST' == $request->getMethod()) {
        try {

            $this->validateForm($form,$request);

            $newItem = $form->getData();

            $em->persist($newItem);
            $em->flush();
            $message  = $this->container->getParameter('form_submit_success');
            $session->setFlash('success', $message);
            $url = $this->generateUrl('Spri_audit_list');

            return $this->redirect($url);

        } catch (FormException $e) {
            $session->setFlash('error', sprintf('Erreur Formulaire : "%s"',$e->getMessage()));
        } catch (\Exception $e) {
            die(var_dump($e->getMessage()));
            $session->setFlash('error', sprintf('Erreur inconnue !  Contactez l\'ADMIN'.$e->getMessage()));
        }
    }

    return $this->render('SpriAuditBundle:Audit:new.html.twig', array('form'=>$form->createView()));
}

【讨论】:

  • 我仍然有相同的结果。
  • 我能想到的最后一件事是尝试将级联持久性添加到 Ressource 实体。
  • 我不明白你在想什么!?
  • 正在添加的资源,它们是作为新资源实体插入还是已在数据库中管理实体?
  • 它们已经存在于数据库中,我只在审核表单中选择它们
猜你喜欢
  • 2012-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多