dro7152 2017-02-20 03:37
浏览 53
已采纳

Symfony:在我的“添加”控制器中,如何让这个关联的实体得到更新?

I have 2 entities: Article and Author. Here's my "add" controller for ArticleController.php. I'm trying to see if the author exists (based on email). If he does exist, I'd like to grab the new first/last name and update the existing entry. If he doesn't exist then I'd like to add the new one it.

New Authors get added just fine if I remove my "if" and setAuthor line. I can't get the names of existing Authors to get updated as I'd expect though!

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(),
    ));
}

Here's the Article entity

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
 * Article
 *
 * @ORM\Table(name="article")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ArticleRepository")
 * @UniqueEntity(fields={"name"}, message="Note: That article already existed.")
 */
class Article
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255, unique=true)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="text", nullable=true)
     */
    private $description;

    /**
     * @var string
     *
     * @ORM\Column(name="thumbnail", type="string", length=255, nullable=true)
     */
    private $thumbnail;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created_date", type="datetime")
     */
    private $createdDate;

    /**
     * @ORM\ManyToOne(targetEntity="Author", inversedBy="articles", cascade={"persist"})
     * @ORM\JoinColumn(name="author_id", referencedColumnName="id")
     * @Assert\Valid()
     */
    private $author;


    /**
     * @ORM\OneToMany(targetEntity="Review", mappedBy="article")
     */
    private $reviews;

    public function __construct()
    {
        $this->reviews = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Article
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set description
     *
     * @param string $description
     *
     * @return Article
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Set thumbnail
     *
     * @param string $thumbnail
     *
     * @return Article
     */
    public function setThumbnail($thumbnail)
    {
        $this->thumbnail = $thumbnail;

        return $this;
    }

    /**
     * Get thumbnail
     *
     * @return string
     */
    public function getThumbnail()
    {
        return $this->thumbnail;
    }

    /**
     * Set createdDate
     *
     * @param \DateTime $createdDate
     *
     * @return Article
     */
    public function setCreatedDate($createdDate)
    {
        $this->createdDate = $createdDate;

        return $this;
    }

    /**
     * Get createdDate
     *
     * @return \DateTime
     */
    public function getCreatedDate()
    {
        return $this->createdDate;
    }

    /**
     * Set authorId
     *
     * @param integer $authorId
     *
     * @return Article
     */
    public function setAuthorId($authorId)
    {
        $this->authorId = $authorId;

        return $this;
    }

    /**
     * Get authorId
     *
     * @return int
     */
    public function getAuthorId()
    {
        return $this->authorId;
    }

    /**
     * Set author
     *
     * @param \AppBundle\Entity\Author $author
     *
     * @return Article
     */
    public function setAuthor(\AppBundle\Entity\Author $author = null)
    {
        $this->author = $author;

        return $this;
    }

    /**
     * Get author
     *
     * @return \AppBundle\Entity\Author
     */
    public function getAuthor()
    {
        return $this->author;
    }

    /**
     * Add review
     *
     * @param \AppBundle\Entity\Review $review
     *
     * @return Article
     */
    public function addReview(\AppBundle\Entity\Review $review)
    {
        $this->reviews[] = $review;

        return $this;
    }

    /**
     * Remove review
     *
     * @param \AppBundle\Entity\Review $review
     */
    public function removeReview(\AppBundle\Entity\Review $review)
    {
        $this->reviews->removeElement($review);
    }

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

    public function __toString() {
        return $this->name;
    }

}

Here's the form:

The form

Thanks in advance for any response. Oh, also, is this an acceptable place for such logic? I'm going to move the if into a helper class to be used in other controllers ... but is a controller a good spot for calling this logic even?

UPDATE: Based on sakhunzai's answer this is currently working. These are 2 methods in my article controller.

But I still have some questions regarding best practices. IF anyone can answer those (in a comment on sakhunzai's answer) I'd be very grateful!

   protected function getAuthor(\AppBundle\Entity\Author $author){

        $em = $this->getDoctrine()->getManager();
        $email = $author->getEmail();

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

        if($existingAuthor){
            $existingAuthor->setFirstName($author->getFirstName());
            $existingAuthor->setLastName($author->getLastName());
            $author = $existingAuthor;
        } else {
            $date = new \DateTime("now");
            $author->setCreatedDate($date);
            $em->persist($author);
        }

        $em->flush();

        return $author;
    }

    /**
     * Creates a new article entity.
     *
     * @Route("/new", name="article_new")
     * @Method({"GET", "POST"})
     */
    public function newAction(Request $request)
    {
        $article = new Article();
        $form = $this->createForm('AppBundle\Form\ArticleType', $article);
        $form->handleRequest($request);

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


            //Update existing author or create new
            $em = $this->getDoctrine()->getManager();
            $author = $this->getAuthor($article->getAuthor());
            //Set the author
            $article = $form->getData();
            $article->setAuthor($author);
            //Set Created Date
            $date = new \DateTime("now");
            $article->setCreatedDate($date);
            $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(),
        ));
    }
  • 写回答

2条回答 默认 最新

  • douhao2548 2017-02-20 05:16
    关注

    I think you need to do something like this (not tested) e.g add new method getAuthor in your article controller and call as follow

        /**
         * @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(),
            ));
        }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 visionmaster启动失败,提示为“机器不满足授权而被禁用”
  • ¥50 用logisim设计16位单时钟周期cpu
  • ¥15 IDEA中圈复杂度如何具体设置
  • ¥50 labview采集不了数据
  • ¥15 请上面代码做什么处理或什么混淆
  • ¥15 英雄联盟自定义房间置顶
  • ¥15 W5500网线插上无反应
  • ¥15 如何用字典的Key,显示在WPF的xaml中
  • ¥15 weautomate读取Excel表格信息然后填写到网页一直报错,如何解决?
  • ¥15 C#如何在Webview2中获取网页验证码