Mysql
 sql >> Base de données >  >> RDS >> Mysql

Désactiver la contrainte de clé étrangère Doctrine

Par définition vous ne pouvez pas supprimer l'enregistrement vers lequel pointe la clé étrangère sans définir la clé sur null (onDelete="SET NULL" ) ou en cascade l'opération de suppression (Il y a deux options - Niveau ORM :cascade={"remove"} | niveau base de données :onDelete="CASCADE" ).
Il existe l'alternative de définir une valeur par défaut d'un enregistrement encore existant , mais vous devez le faire manuellement, je ne pense pas que Doctrine supporte ce "prêt à l'emploi" (veuillez me corriger si je me trompe, mais dans ce cas, la définition d'une valeur par défaut n'est pas souhaitée de toute façon).

Cette rigueur reflète le concept d'avoir des contraintes de clé étrangère ; comme @Théo a dit :

La suppression réversible (déjà mentionnée) est une solution, mais vous pouvez également ajouter un removed_page_id supplémentaire colonne que vous synchronisez avec le page_id juste avant de le supprimer dans un preRemove gestionnaire d'événements (rappel du cycle de vie). Je me demande si ces informations ont une valeur, mais je suppose que vous en avez une certaine utilité, sinon vous ne poseriez pas cette question.

Je ne prétends certainement pas que ce soit une bonne pratique , mais c'est au moins quelque chose que vous pouvez utiliser pour votre cas marginal. Donc quelque chose dans la lignée de :

Dans votre Revision :

/**
 * @ORM\ManyToOne(targetEntity="Page", cascade="persist")
 * @ORM\JoinColumn(name="page_id", referencedColumnName="id", onDelete="SET NULL")
 */
private $parentPage;

/**
 * @var int
 * @ORM\Column(type="integer", name="removed_page_id", nullable=true)
 */
protected $removedPageId;

Et ensuite dans votre Page :

/** 
 * @ORM\PreRemove 
 */
public function preRemovePageHandler(LifecycleEventArgs $args)
{
    $entityManager = $args->getEntityManager();
    $page = $args->getEntity();
    $revisions = $page->getRevisions();
    foreach($revisions as $revision){
        $revision->setRemovedPageId($page->getId());
        $entityManager->persist($revision);
    }
    $entityManager->flush();
}

Alternativement, vous pouvez bien sûr déjà définir le bon $removedPageId valeur lors de la construction de votre Revision , vous n'avez même pas besoin d'exécuter un rappel de cycle de vie lors de la suppression.