Symfony удалить ManyToMany связанный объект, когда одна часть пуста? - PullRequest
1 голос
/ 24 сентября 2019

Я пытаюсь удалить неиспользуемые теги.Хотя связь между Post и Tag была удалена, тег post-link не удаляется.

«orphanRemoval» не работает, поскольку он удалил все.Каскад «удалить» не удаляет.

Запись объекта:

class Post implements \JsonSerializable
{
   /**
    * @ORM\ManyToMany(targetEntity="App\Entity\Cms\PostTag", inversedBy="posts", cascade={"persist", "remove"})
    * @ORM\JoinTable(name="post_tag_taxonomy")
    * @Assert\Count(max="5")
    */
    private $tags;
}

Тег объекта:

class PostTag {
    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Cms\Post", mappedBy="tags")
     */
     private $posts;
}

Вот аналогичный пример, но для Java. Как удалить связанный объект ManyToMany, когда одна часть пуста?

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Решение:

/**
 * @ORM\PostUpdate()
 */
public function postUpdate(LifecycleEventArgs $args)
{
    /** @var PersistentCollection $tags */
    $tags = $args->getEntity()->getTags();
    if ($tags->isDirty() && ($deleted = $tags->getDeleteDiff())) {
        $em = $args->getEntityManager();

        foreach ($deleted as $tag) {
            if ($tag->getPosts()->count() === 1) {
                $em->remove($tag);
                $em->flush($tag);
            }
        }
    }
}
0 голосов
/ 24 сентября 2019

Я предлагаю вам использовать preUpdate событие из Обратные вызовы жизненного цикла доктрины .В случае обновления сообщения вы указываете доктрине проверить, есть ли изменение тега (в данном случае это значение равно NULL), если да, то запросите проверку тега, если какие-либо сообщения все еще используют его.

Короче говоря,вам нужно:

Добавить @ORM \ HasLifecycleCallbacks перед вашим классом, чтобы включить жизненные циклы.

Добавить функцию preUpdate в класс Post:

    /**
     * @ORM\PreUpdate
     * @param PreUpdateEventArgs $event
     */
    public function clearChangeSet(PreUpdateEventArgs $event)
    {
        if ($event->hasChangedField('field_you_want_to_check') 
        ) {
            $em = $event->getEntityManager();
            // Now use the entityManager to query the tag and check.
        }
    }

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

Обновление: как указано, для ассоциаций в сущности вы не можете получить изменения с помощью $event->hasChangedField, используйте метод в Symfony 3 / Doctrine - Получить изменения ассоциаций в наборе изменений сущностей

...