Podle definice nemůžete smazat záznam, na který cizí klíč ukazuje, aniž byste klíč nenastavili na hodnotu null (onDelete="SET NULL"
) nebo kaskádování operace odstranění (Jsou dvě možnosti
- Úroveň ORM:cascade={"remove"}
| úroveň databáze:onDelete="CASCADE"
).
Existuje alternativa nastavení výchozí hodnoty stále existujícího záznamu
, ale musíte to udělat ručně, nemyslím si, že Doctrine toto „out-of-the-box“ podporuje (opravte mě, pokud se mýlím, ale v tomto případě není nastavení výchozí hodnoty stejně žádoucí).
Tato přísnost odráží koncept omezení cizího klíče; jak řekl @Théo:
Soft delete (již zmíněno) je jedno řešení, ale můžete také přidat další removed_page_id
sloupec, který synchronizujete s page_id
těsně předtím, než jej smažete v preRemove
obsluha události (zpětné volání životního cyklu). Zajímalo by mě, zda takové informace mají nějakou hodnotu, ale předpokládám, že pro ně máte nějaké využití, jinak byste tuto otázku nepokládali.
Rozhodně netvrdím, že je to dobrý postup , ale je to alespoň něco, co můžete použít pro svůj okrajový kufr. Takže něco ve smyslu:
Ve vaší 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;
A poté na vaší 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();
}
Alternativně byste samozřejmě již mohli nastavit správné $removedPageId
hodnotu během vytváření vaší Revision
, pak při odebrání ani nemusíte provádět zpětné volání životního cyklu.