Php Symfony:在我的“添加”控制器中,如何更新此关联实体?

Php Symfony:在我的“添加”控制器中,如何更新此关联实体?,php,doctrine,symfony,Php,Doctrine,Symfony,我有两个实体:文章和作者。这是我为ArticleController.php添加的控制器。我想看看作者是否存在于电子邮件中。如果他确实存在,我想获取新的名字/姓氏并更新现有条目。如果他不存在,那么我想把新的加进去 如果我删除if和setAuthor行,新作者就可以添加了。我不能像我期望的那样更新现有作者的名字 public function newAction(Request $request) { $article = new article(); $form = $this-

我有两个实体:文章和作者。这是我为ArticleController.php添加的控制器。我想看看作者是否存在于电子邮件中。如果他确实存在,我想获取新的名字/姓氏并更新现有条目。如果他不存在,那么我想把新的加进去

如果我删除if和setAuthor行,新作者就可以添加了。我不能像我期望的那样更新现有作者的名字

public function newAction(Request $request)
{
    $article = new article();
    $form = $this->createForm('AppBundle\Form\articleType', $article);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        $em = $this->getDoctrine()->getManager();
        // check to see if the email already exists.
        $existingAuthor = $em
            ->getRepository('AppBundle:Author')
            ->findOneByEmail($article->getAuthor()->getEmail());

        if ($existingAuthor) {

            //if the email does exist, grab the incoming name and update the existing name with it.
            $existingAuthor->setFirstName($article->getAuthor()->getFirstName());
            $existingAuthor->setLastName($article->getAuthor()->getLastName());
            $author = $existingAuthor;

        } else {
            //Other wise it's a new author. Set the creation timestamp.
            $date = new \DateTime("now");
            $article->getAuthor()->setCreatedDate($date);
        }

        $article->setAuthor($author);

        //Set Created Date
        $date = new \DateTime("now");
        $article->setCreatedDate($date);

        //Persist to database.

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

        return $this->redirectToRoute('article_show', array('id' => $article->getId()));

    }

    return $this->render('article/new.html.twig', array(
        'article' => $article,
        'form' => $form->createView(),
    ));
}
这里是文章实体


关系的级联部分是否正确设置,即如下所示

 /**
 * @OneToOne(... cascade={"persist"})
 */

我认为您需要做一些未经测试的事情,例如在您的文章控制器中添加新方法getAuthor,并按如下方式调用

    /**
     * @param Request $request
     * @return AppBundle\Entity\Author;
     */
    protected function getAuthor(EntityManager $em, Request $request){

        $email = $request->get('email');

        $author = $em->getRepository('AppBundle:Author')->findOneByEmail($email);

        if(!$author){
            $author= new Author();
            $author->setLastName($email);
            $author->setFirstName($request->get('first_name'));
            $author->setLastName($request->get('last_name'));
            $em->persist($author);
            $em->flush();
        }

        return $author;
    }


    public function newAction(Request $request)
    {
        $article = new article();
        $form = $this->createForm('AppBundle\Form\articleType', $article);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $em = $this->getDoctrine()->getManager();
            $author = $this->getAuthor($em,$request);

            $article = $form->getData();
            $article->setAuthor($author);
            $em->persist($article);
            $em->flush($article);

            return $this->redirectToRoute('article_show', array('id' => $article->getId()));

        }

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

行->findOneByEmail$article->getAuthor->getEmail;似乎模棱两可。你函数的第一行是创建新文章,我怀疑它还没有指定作者,这意味着你试图获取作者的上面一行将返回null。谢谢你的回复。您是正确的,它将返回NULL,但仅当提交的电子邮件地址$article->getAuthor->getEmail不存在时$article->getAuthor在文章持续之前返回完美数据。。。设置为$article->setAuthor$author的作者没有更新。我是不是误解了坚持的作用?我以为它已经更新了相关数据。如果没有,最好的处理方法是什么?非常感谢。如果作者是有效作者,则无需通过$article->setAuthor$Author;再次更新。但我怀疑的是,你们试图一次完成文章和作者的创作。如果可能的话,请添加表格的截图。我已经附上了截图。通过使用setAuthor,我希望当文章被持久化时,authorfirstname/lastname会被更新。据我所知,是这样的。谢谢我已经包含了文章实体以供参考。非常感谢!根据你的回答,我能让它工作。我确实有一些问题,但我希望你不介意回答。(某物代表什么?)?2:为什么要通过$em而不是获得一个新的内存效率?3:为什么要通过请求而不是直接通过作者——我修改了你的方法来接受作者,这是不是做错了什么?4:有人告诉我,如果我持久化$em获得的实体,那么它只会更新,而不会插入。在移动到else内部之前,它似乎不会崩溃。我说错了吗?1修复了“sth”问题,抱歉英语不好,2是的,最好避免额外调用/并创建对象3您的代码很复杂,因为当您首先调用$article->getAuthor时,author确实存在,并且从代码中看不到其意图,当你正在更新现有文章而不是新文章时,你的流程可能是正确的。4读了这篇文章,你的概念会被澄清,有人会告诉你更多关于对象持久性的信息。感谢大家的回答、澄清和阅读材料!
 /**
 * @OneToOne(... cascade={"persist"})
 */
    /**
     * @param Request $request
     * @return AppBundle\Entity\Author;
     */
    protected function getAuthor(EntityManager $em, Request $request){

        $email = $request->get('email');

        $author = $em->getRepository('AppBundle:Author')->findOneByEmail($email);

        if(!$author){
            $author= new Author();
            $author->setLastName($email);
            $author->setFirstName($request->get('first_name'));
            $author->setLastName($request->get('last_name'));
            $em->persist($author);
            $em->flush();
        }

        return $author;
    }


    public function newAction(Request $request)
    {
        $article = new article();
        $form = $this->createForm('AppBundle\Form\articleType', $article);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $em = $this->getDoctrine()->getManager();
            $author = $this->getAuthor($em,$request);

            $article = $form->getData();
            $article->setAuthor($author);
            $em->persist($article);
            $em->flush($article);

            return $this->redirectToRoute('article_show', array('id' => $article->getId()));

        }

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