Merhaba arkadaşlar, bugün başımı çok ağrıtan bir Laravel detayından bahsedeceğim. Projede soft delete (yumuşak silme) özelliğini kullanıyordum ve her şey güllük gülistanlıktı, ta ki ilişkili modelleri çekmeye çalışana kadar! Silinmiş bir kullanıcının yorumlarını listelemeye çalıştığımda ekran bomboş kalınca "Benim verilerim nerede?!" diye kafayı yemiştim. Meğerse soft delete, ilişkileri de sessiz sedasız etkiliyormuş.
Soft Delete'in Gizli Etkisi
Laravel'de bir modelde soft delete aktif ettiğinizde, o modelden silinen kayıtlar veritabanından fiziksel olarak silinmez, sadece `deleted_at` sütunu tarih ile doldurulur. Ancak, varsayılan olarak tüm sorgular otomatik olarak `deleted_at` NULL olan kayıtları getirir. Sorun şu ki, bu filtreleme ilişkiler için de geçerli!
Diyelim ki `User` ve `Post` modeliniz var. User soft delete kullanıyor. Klasik ilişki sorgunuz şöyle:
Eğer ID'si 1 olan kullanıcı silinmişse, `$user` null olacak ve `$posts` sorgusu hiç çalışmayacak. Ama ya kullanıcı silinmemişse ve siz onun tüm post'larını (silinenler dahil) görmek istiyorsanız? İşte tam burada `withTrashed()` devreye giriyor.
İlişkilerde withTrashed() Kullanımı
`withTrashed()` metodu, ilişki sorgusuna "silinmiş kayıtları da getir" talimatını verir. Kullanımı oldukça basit:
Bu şekilde, kullanıcıya ait deleted_at dolu olsa bile tüm post'ları çekebilirsiniz. Ancak dikkat! Bu sefer de sadece silinmiş olanları getirmek isteyebilirsiniz. Onun için de `onlyTrashed()` metodu var.
Hangi İlişki Türlerinde Çalışır?
Önemli bir nokta: `withTrashed()` ve `onlyTrashed()` metodları sadece hasMany, hasOne, belongsTo ve morphMany gibi temel ilişkilerde çalışır. Eğer `hasManyThrough` gibi daha kompleks bir ilişkiniz varsa, manuel bir sorgu yazmanız veya scope tanımlamanız gerekebilir.
İşte benim kullandığım en temiz çözüm, modelimde her iki ihtimale yönelik ilişkileri tanımlamak:
Bu yapı, kodu daha okunabilir ve amaca yönelik hale getiriyor.
Sonuç olarak, Laravel'in soft delete özelliği harika bir araç ama ilişkiler konusunda sinsi davranabiliyor. `withTrashed()` metodunu doğru yerde kullanmak, veri kaybı yaşamadan esnek sorgular yazmanızı sağlar.
Siz Laravel'de soft delete kullanırken benzer bir sorunla karşılaştınız mı? Ya da ilişkili silinmiş verileri yönetmek için farklı bir yönteminiz var mı? Yorumlarda paylaşalım!
Laravel'de bir modelde soft delete aktif ettiğinizde, o modelden silinen kayıtlar veritabanından fiziksel olarak silinmez, sadece `deleted_at` sütunu tarih ile doldurulur. Ancak, varsayılan olarak tüm sorgular otomatik olarak `deleted_at` NULL olan kayıtları getirir. Sorun şu ki, bu filtreleme ilişkiler için de geçerli!
Diyelim ki `User` ve `Post` modeliniz var. User soft delete kullanıyor. Klasik ilişki sorgunuz şöyle:
PHP:
// User modelinde
public function posts()
{
return $this->hasMany(Post::class);
}
// Kullanım
$user = User::find(1);
$posts = $user->posts; // Sadece silinmemiş post'ları getirir!
Eğer ID'si 1 olan kullanıcı silinmişse, `$user` null olacak ve `$posts` sorgusu hiç çalışmayacak. Ama ya kullanıcı silinmemişse ve siz onun tüm post'larını (silinenler dahil) görmek istiyorsanız? İşte tam burada `withTrashed()` devreye giriyor.
`withTrashed()` metodu, ilişki sorgusuna "silinmiş kayıtları da getir" talimatını verir. Kullanımı oldukça basit:
PHP:
// User modelinde, silinen post'ları da getiren özel bir ilişki
public function allPosts()
{
return $this->hasMany(Post::class)->withTrashed();
}
// Veya dinamik olarak sorgu üzerinde kullanma
$user = User::find(1);
$allPosts = $user->posts()->withTrashed()->get();
Bu şekilde, kullanıcıya ait deleted_at dolu olsa bile tüm post'ları çekebilirsiniz. Ancak dikkat! Bu sefer de sadece silinmiş olanları getirmek isteyebilirsiniz. Onun için de `onlyTrashed()` metodu var.
Önemli bir nokta: `withTrashed()` ve `onlyTrashed()` metodları sadece hasMany, hasOne, belongsTo ve morphMany gibi temel ilişkilerde çalışır. Eğer `hasManyThrough` gibi daha kompleks bir ilişkiniz varsa, manuel bir sorgu yazmanız veya scope tanımlamanız gerekebilir.
İşte benim kullandığım en temiz çözüm, modelimde her iki ihtimale yönelik ilişkileri tanımlamak:
PHP:
class User extends Model
{
use SoftDeletes;
// Sadece silinmemiş post'lar (Varsayılan)
public function posts()
{
return $this->hasMany(Post::class);
}
// Tüm post'lar (silinenler dahil)
public function postsWithTrashed()
{
return $this->hasMany(Post::class)->withTrashed();
}
// Sadece silinmiş post'lar
public function postsOnlyTrashed()
{
return $this->hasMany(Post::class)->onlyTrashed();
}
}
Bu yapı, kodu daha okunabilir ve amaca yönelik hale getiriyor.
Sonuç olarak, Laravel'in soft delete özelliği harika bir araç ama ilişkiler konusunda sinsi davranabiliyor. `withTrashed()` metodunu doğru yerde kullanmak, veri kaybı yaşamadan esnek sorgular yazmanızı sağlar.
Siz Laravel'de soft delete kullanırken benzer bir sorunla karşılaştınız mı? Ya da ilişkili silinmiş verileri yönetmek için farklı bir yönteminiz var mı? Yorumlarda paylaşalım!