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.
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With