ManyToMany无法反向保存任务

时间:2018-04-23 19:07:21

标签: symfony doctrine many-to-many

拥有方:

/**
 * Task
 *
 * @ORM\Table(name="task")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\TaskRepository")
 */
class Task
{
//...
    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="tasks", cascade={"all"})
     * @ORM\JoinTable(name="categories_tasks")
     */
    private $categories;

    public function __construct() {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }

    // ...

    public function setCategories(Category $categories)
    {
        $this->categories[] = $categories;
    }

反面:

/**
 * Category
 *
 * @ORM\Table(name="category")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository")
 */
class Category
{


    // ...

    /**
     * @ORM\ManyToMany(targetEntity="Task", mappedBy="categories", cascade={"persist"})
     * @ORM\JoinTable(name="categories_tasks")
     */
    private $tasks;

    public function __construct() {
        $this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
    }


    //...

    public function getTasks()
    {
        return $this->tasks;
    }

    public function setTasks(Task $task)
    {
        $this->tasks = $task;
    }

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

    public function addTask(Task $task)
    {
        if (!$this->tasks->contains($task)) {
            $this->tasks->add($task);
            $task->setCategories($this);

            return $this;
        }
    }

    public function removeTask (Task $task)
    {
        if ($this->tasks->contains($task)) {
            $this->tasks->remove($task);
            $task->removeCategory($this);
        }
    }
}

我可以使用Task保存类别。我无法使用类别保存任务。我仔细研究了Association Mapping from Doctrine's website但没有取得好成绩。我花了最后一小时从堆栈中读取类似的情况,当然我尝试添加一些代码,但仍然没有可行的解决方案。我错过了什么?

我通过代码部分地做事:

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

$tasks = $category->getTasks();
foreach($tasks as $t)
{
    $t->setCategories($category);
    $em->persist($t);
}
$em->flush();

但它并不完美,我不想这样做,因为我很确定我做了一些轻易的错误。

3 个答案:

答案 0 :(得分:0)

尝试在您的实体中添加这些方法:

/**
 * Add category
 *
 * @param \AppBundle\Entity\Category $category
 *
 * @return Task
 */
public function addCategory(Category $category)
{
    $this->categories[] = $competition;
    $category->addTask($this);

    return $this;
}

/**
 * Add task
 *
 * @param \AppBundle\Entity\Task $task
 *
 * @return Category
 */
public function addTask(Task $task)
{
    $this->tasks[] = $task;
    $task->addCategory($this);

    return $this;
}

然后,

$em = $this->getDoctrine()->getManager();
$task->addCategory($category)
$em->persist($task);
$em->flush();

$em = $this->getDoctrine()->getManager();
$category->addTask($task)
$em->persist($category);
$em->flush();

答案 1 :(得分:0)

我会说几乎像@Benoit,但实际上,我认为你不需要坚持以这种方式添加的实体(如果需要的话,坚持新创建的实体会更有意义。)

所以

$em = $this->getDoctrine()->getManager();
$task->addCategory($category)
$em->persist($task);
$em->flush();

变为

$em = $this->getDoctrine()->getManager();
$task->addCategory($category);
$em->flush();

编辑:假设实体经理处理$ task对象

Edit2(来自评论):由于您的类别已存在且已获取,请从代码中删除持久性($ category)。

答案 2 :(得分:0)

你可以尝试这个解决方案(类似于以前的变种)

应用\实体\任务

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 */
class Task
{
    // ...

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Category", inversedBy="tasks", cascade={"all"})
     */
    private $categories;

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

    public function getCategories(): Collection
    {
        return $this->categories;
    }

    public function addCategory(Category $category): self
    {
        if (!$this->categories->contains($category)) {
            $this->categories[] = $category;
        }

        return $this;
    }

    public function removeCategory(Category $category): self
    {
        if ($this->categories->contains($category)) {
            $this->categories->removeElement($category);
        }

        return $this;
    }
}

应用\实体\分类

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 */
class Category
{
    // ...

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Task", mappedBy="categories")
     */
    private $tasks;

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

    public function getId()
    {
        return $this->id;
    }

    public function getTasks(): Collection
    {
        return $this->tasks;
    }

    public function addTask(Task $task): self
    {
        if (!$this->tasks->contains($task)) {
            $this->tasks[] = $task;
            $task->addCategory($this);
        }

        return $this;
    }

    public function removeTask(Task $task): self
    {
        if ($this->tasks->contains($task)) {
            $this->tasks->removeElement($task);
            $task->removeCategory($this);
        }

        return $this;
    }
}

保存过程:

// ...
$task->addCategory($category);
$em->persist($task);
$em->flush();

// ...
$category->addTask($task);
$em->persist($category);
$em->flush();

希望帮助

你的editAction中的PS可以尝试以这种方式保存:

if ($editingForm->isSubmited() && $editingForm->isSubmited()) {
    $em->persist($category);
    $em->flush();
}