Według definicji nie można usunąć rekordu, na który wskazuje klucz obcy bez ustawienia klucza na null (onDelete="SET NULL"
) lub kaskadowanie operacji usuwania (Są dwie opcje
- Poziom ORM:cascade={"remove"}
| poziom bazy danych:onDelete="CASCADE"
).
Istnieje alternatywa ustawianie domyślnej wartości wciąż istniejącego rekordu
, ale musisz to zrobić ręcznie, nie sądzę, że Doctrine obsługuje to „niestandardowe” (proszę mnie poprawić, jeśli się mylę, ale w tym przypadku ustawienie domyślnej wartości i tak nie jest pożądane).
Ta ścisłość odzwierciedla koncepcję posiadania ograniczeń kluczy obcych; jak @Théo powiedział:
Usuwanie miękkie (już wspomniane) to jedno z rozwiązań, ale możesz również dodać dodatkowy removed_page_id
kolumna, którą synchronizujesz z page_id
tuż przed usunięciem go w preRemove
obsługa zdarzeń (odwołanie zwrotne cyklu życia). Zastanawiam się, czy takie informacje mają jakąkolwiek wartość, ale myślę, że przyda Ci się to, bo inaczej nie zadałbyś tego pytania.
Zdecydowanie nie twierdzę, że to dobra praktyka , ale przynajmniej jest to coś, czego możesz użyć w przypadku krawędzi. A więc coś w stylu:
W Twojej 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 potem na swojej 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();
}
Alternatywnie możesz oczywiście już ustawić poprawny $removedPageId
wartość podczas konstruowania Revision
, nie musisz nawet wykonywać wywołania zwrotnego cyklu życia po usunięciu.