Mysql
 sql >> Database >  >> RDS >> Mysql

Disabilita il vincolo della chiave esterna di Doctrine

Per definizione non è possibile eliminare il record a cui punta la chiave esterna senza impostare la chiave su null (onDelete="SET NULL" ) o sovrapponendo l'operazione di eliminazione (Sono disponibili due opzioni - Livello ORM:cascade={"remove"} | livello di database:onDelete="CASCADE" ).
Esiste l'alternativa di impostazione di un valore predefinito di un record ancora esistente , ma devi farlo manualmente, non credo che Doctrine supporti questo "out-of-the-box" (correggimi se sbaglio, ma in questo caso l'impostazione di un valore predefinito non è comunque desiderata).

Questa severità riflette il concetto di avere vincoli di chiave esterna; come ha detto @Théo:

L'eliminazione graduale (già menzionata) è una soluzione, ma potresti anche aggiungere un ulteriore removed_page_id colonna che sincronizzi con page_id appena prima di eliminarlo in un preRemove gestore di eventi (callback del ciclo di vita). Mi chiedo se tali informazioni abbiano un valore, ma immagino che tu possa utilizzarle, altrimenti non faresti questa domanda.

Sicuramente non sto affermando che questa sia una buona pratica , ma è almeno qualcosa che puoi usare per il tuo caso limite. Quindi qualcosa nella linea di:

Nella tua 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;

E poi nella tua 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();
}

In alternativa potresti ovviamente già impostare il corretto $removedPageId valore durante la costruzione della tua Revision , quindi non è nemmeno necessario eseguire un callback del ciclo di vita alla rimozione.