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

时间:2017-02-20 03:37:01

标签: php doctrine symfony

我有2个实体:文章和作者。这是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(),
    ));
}

这是文章实体

<?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;
    }

}

以下是表格:

The form

提前感谢您的回复。哦,这也是这个逻辑的可接受的地方吗?我要将if移动到辅助类中以便在其他控制器中使用...但是控制器是调用这个逻辑的好地方吗?

更新:根据sakhunzai的回答,目前正在运作。这些是我的文章控制器中的两种方法。

但我仍然对最佳做法有一些疑问。如果有人能回答这些问题(在评论sakhunzai的回答中),我将非常感激!

   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 个答案:

答案 0 :(得分:1)

我认为您需要做类似这样的事情(未经测试),例如在文章控制器中添加新方法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(),
        ));
    }

答案 1 :(得分:0)

关系的级联部分是否设置正确(即下面)?

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