Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deleting entities in cascade not working in ManyToMany relation

I have a parent entity Category and a child entity Article. They are defined by a ManyToMany relation. One article can be taged in one or more category and every Category can be tagged in more than one Article.

WHAT I TRY TO DO
I would like that when I delete a Category, every Article tagged in the Category are also deleted BUT only if they are not tagged by an other Category.

WHAT I HAVE ALREADY TESTED
I tested with 2 category (id=1 and id=2) and with two articles (id=71 and id=91). article 71 has both category 1 and 2. Article 91 is linked only with category 2.
So when deleting category 2 I expect to delete article 91 but not article 71 (as this one is still linked with category_1)

But none of this happenned whatever I tried...

In the following picture I summed up what I get using different strategies (1/cascade={"remove"} , 2/orphanRemoval=true and 3/ondelete="CASCADE" ).
In green the removal from the database.

enter image description here

MY CODE (PART OF CODE)

in the controller

public function deleteCategory(Category $category)
{
  $em = $this->getDoctrine()->getManager();
  $em->remove($category);
  $em->flush();
}

for strategy 1/ cascade={"remove"}

 // IN CLASS/ENTITY CATEGORY - OWNER OF THE RELATION
 * @ORM\ManyToMany(targetEntity="Article", inversedBy="categories",  cascade={ "remove"})
 private $articles;

 // IN CLASS/ENTITY ARTICLE 
 * @ORM\ManyToMany(targetEntity="Category", mappedBy="articles")
 private $categories;

for strategy 2/ orphanRemoval=true

 // IN CLASS/ENTITY CATEGORY - OWNER OF THE RELATION
 * @ORM\ManyToMany(targetEntity="Article", inversedBy="categories",  orphanRemoval=true)
 private $articles;

 // IN CLASS/ENTITY ARTICLE 
 * @ORM\ManyToMany(targetEntity="Category", mappedBy="articles")
 private $categories;

for strategy 3/ onDelete="CASCADE"

 // IN CLASS/ENTITY CATEGORY - OWNER OF THE RELATION
 * @ORM\ManyToMany(targetEntity="Article", inversedBy="categories")
 private $articles;

 // IN CLASS/ENTITY ARTICLE 
 * @ORM\ManyToMany(targetEntity="Category", mappedBy="articles")
 * @ORM\JoinColumn(onDelete="CASCADE")

 private $categories;

MY QUESTION

is there some other way of doing it but the 3 strategies I already tried or those removals have to be done in the controller?

like image 939
Alexis_D Avatar asked Dec 16 '14 14:12

Alexis_D


1 Answers

You can't do this using just cascading features as far as I can think of.

A clean solution would be to create an listener which subscribes to the preRemove events. You can then check when a category is deleted and find all articles from that category which do not have any other categories and remove those as well.

like image 158
Waaghals Avatar answered Oct 16 '22 09:10

Waaghals