Achref Bannouri
Achref Bannouri

Reputation: 25

Delete child only doctrine2 symfony

I'm trying to delete Child, but it also deletes its parent and all other children Here's my parent entity : annonce

/**
     * @ORM\OneToMany(targetEntity="Candidature", mappedBy="annonce",orphanRemoval=true )
     */
    private $candidatures;

and here's my child entity: candidature

/**
     * @ORM\ManyToOne(targetEntity="Annonce", inversedBy="candidatures" )
     * @ORM\JoinColumn(name="id_annonce", referencedColumnName="id",nullable=false)
     */
    private $annonce;

here's my delete action on parent:

public function supprimerAction($id)
    {

        $em=$this->getDoctrine()->getManager();
        $annonce=$em->getRepository(Annonce::class)->find($id);
        $em->remove($annonce);
        $em->flush();
        return $this->redirectToRoute("mesAnnonces");
    }

and here's my delete action on child candidature

 public function supprimerAction($id)
    {

        $em=$this->getDoctrine()->getManager();
        $candidature=$em->getRepository(Candidature::class)->find($id);
        $em->remove($candidature);
        $em->flush();
        return $this->redirectToRoute("mesCandidatures");
    }

Upvotes: 0

Views: 1444

Answers (1)

Preciel
Preciel

Reputation: 2827

Rather than orphanRemoval, you should use onDelete=CASCADE.

As Candidature::annonce can't be false, you will never have any orphans, it's not possible.
All you need is to delete every Candidature entry from the DB when you delete the related Annonce entry.
And deleting a single Candidature won't affect the parent Annonce this way.

/**
 * @ORM\OneToMany(targetEntity="Candidature", mappedBy="annonce" )
 */
private $candidatures;

/**
 * @ORM\ManyToOne(targetEntity="Annonce", inversedBy="candidatures" )
 * @ORM\JoinColumn(onDelete="CASCADE", nullable=false)
 */
private $annonce;

On a side note, I would suggest to make proper supprimerAction().
At least something like this:

public function supprimerAction(Annonce $annonce) {
    $em=$this->getDoctrine()->getManager();
    $em->remove($annonce);
    $em->flush();

    return $this->redirectToRoute("mesAnnonces");
}

public function supprimerAction(Candidature $candidature) {
    $em=$this->getDoctrine()->getManager();
    $em->remove($candidature);
    $em->flush();

    return $this->redirectToRoute("mesCandidatures");
}

Though, even this isn't proper enough.
There is no form in this, no CSRF token either.
This would be more secure :

public function supprimerAction(Request $request, Annonce $annonce) {
    $form=$this->createFormBuilder()
         ->setAction($this->generateUrl('annonce_supprimer', array('id'=>$annonce->getId())))
         ->setMethod('DELETE')
         ->getForm();

    $form->handleRequest($request);
    if($form->isSubmitted() && $form->isValid()) {
        $em=$this->getDoctrine()->getManager();
        $em->remove($annonce);
        $em->flush();

        return $this->redirectToRoute("mesAnnonces");
    }

    return $this->render('annonce_supprimer.html.twig', array(
        'annonce'=>$annonce,
        'form'=>$form,
    ));
}

public function supprimerAction(Request $request, Candidature $candidature) {
    $form=$this->createFormBuilder()
               ->setAction($this->generateUrl('annonce_supprimer', array('id'=>$candidature->getId())))
               ->setMethod('DELETE')
               ->getForm();

    $form->handleRequest($request);
    if($form->isSubmitted() && $form->isValid()) {
        $em=$this->getDoctrine()->getManager();
        $em->remove($candidature);
        $em->flush();

        return $this->redirectToRoute("mesCandidatures");
    }

    return $this->render('candidature_supprimer.html.twig', array(
        'candidature'=>$candidature,
        'form'=>$form,
    ));
}

Upvotes: 1

Related Questions