ManyToMany не может сохранить задачу на обратной стороне

Сторона владельца:

/**
 * 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. Я не могу сохранять задачи с категорией. Я внимательно изучил Сопоставление ассоциаций с веб-сайта Doctrine, но без хорошего результата. Я провел последний час, читая похожие случаи из стека, и, конечно же, я попытался добавить несколько кодов, но все еще не нашел рабочего решения. Что я скучаю?

Я делаю это частично по коду:

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

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

но это не идеально, и я не хочу идти по этому пути, потому что совершенно уверен, что совершаю простую ошибку.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
0
0
104
3

Ответы 3

Попробуйте добавить этот метод в свои сущности:

/**
 * 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();

SQLSTATE [23000]: Нарушение ограничения целостности: 1062 Повторяющаяся запись «3-6» для ключа «PRIMARY» :( Я делаю простой фильм: dropbox.com/s/6oh6060evshzdu9/… Мне пришлось удалить строку $ category-> addTask ($ task), потому что она вызывает 500

Lukaszy 24.04.2018 10:57

Таким образом, проблема заключается в том, чтобы попытаться сохранить задачи, которые уже связаны с текущей категорией.

Lukaszy 24.04.2018 10:59

Не используйте оба метода на каждой стороне, для вызова сеттеров нужен только один на обратной стороне.

Charlie Lucas 24.04.2018 18:03

Я бы сказал почти как @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) из вашего кода.

Это тоже работает, но здесь та же проблема, что и в решении @Benoit: SQLSTATE [23000]: нарушение ограничения целостности: 1062 Повторяющаяся запись «3-2» для ключа «PRIMARY». Здесь я точно показываю: dropbox.com/s/6oh6060evshzdu9/…

Lukaszy 24.04.2018 15:52

Ваше действие, похоже, является функцией редактирования, тогда я полагаю, что ваша категория уже существует. Затем вы можете удалить все сохраняемые ($ category) из кода вашего действия. Проблема возникает из-за того, что вы пытаетесь создать уже существующую сущность. Просто выполните add (), затем flush ().

Aurelien 24.04.2018 16:10

вы можете попробовать это решение (аналогично предыдущим вариантам)

Приложение \ Сущность \ Задача

<?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();

Надежда помогает

PS в вашем editAction вы можете попробовать сохранить таким образом:

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

Другие вопросы по теме