@dodiş#31498 Aldığınız integrity constraint violation hatası iyi bir şey, demek ki foreign key kullanarak ilişkinin düzensiz şekilde silinmesine engel olarak veritabanında öksüz kayıtların önüne geçmişsiniz. Sadece geriye yazılımsal olarak bu aşamaya gelmeyi engellemek kalıyor.
@dodiş#31498 Direkt kategoriyi silsin ama ürünleri soft delete olarak silsin.
Bu sefer ürünleriniz öksüz kalacak, yani kategorisiz. Bu durumda 3 seçeneğiniz var. Projenizin yapısına göre seçeceksiniz:
1 - Kategoriyi silmeden önce ürünler arasındaki ilişkiyi koparacaksınız ve sonra kategoriyi sileceksiniz.
// Burada $category->products()->getQualifiedForeignKeyName() category_id döner.
$category->products()->update([
$category->products()->getQualifiedForeignKeyName() => null
]);
$category->delete();
Eğer ürünlerin mutlaka bir kategorisi olması gerekiyorsa kategoriyi silmeden önce içindeki ürünleri başka bir kategoriye taşımanız gerekiyor.
$category->products()->update([
'category_id' => $newCategory->id
]);
$category->delete();
2 - Category modeline de SoftDeletes ekleyeceksiniz ve deleted/deleting olayında altındaki ürünleri de sil diyeceksiniz. Böylece ikisi de sistemde soft deleted olarak kalacak:
static::deleting(function ($category) {
$category->products()->delete();
});
3 - Altında ürün olan kategorilerin silinmesine izin vermeyeceksiniz. Bu benim tercih ettiğim yol:
if($category->products()->withTrashed()->count()) {
// ya da if($category->products()->count()) {
abort(400, __('Only empty categories can be deleted.'))
}
$category->delete();
Bunu tercih etmemin sebebi ise, soft deleting iki yönlü bir işlem. Biri silme diğeri ise eski haline getirme yani restore. Eğer restore özelliğini kullanmayacaksam sisteme soft deleting gibi dikkatli kullanılması gereken bir özellik eklemem. Eski kayıtlar arşiv olarak kalsın, veritabanı bütünlüğü bozulmasın, normalizasyon sağlansın isterim. Soft deleting her sorguya where deleted_at is null
ekliyor. Eğer çok fazla kayıtla ilgileniyorsanız bu indeks oluştururken dikkat etmeniz gereken bir nokta. Diğer bir husus ise soft deleting bir Eloquent özelliği, Eloquent kullanmadığınız sorgularda deleted_at sütununu da dahil ederek sorgu yazmanız gerekiyor. Başka bir husus da arşiv tarzı ulaştığınız geçmiş dataların sorgularında withTrashed()
kullanmanız gerekecek.
Yani iyi bir özellik ama dikkatli kullanılması gerekiyor ve sisteme ek bir yük getirdiğinin farkında olmanız lazım. Ben şahsen çok nadiren kullanırım.