v3 - Tüm Sorunlar Çözüldü ✓
Loop içinde attachSongWithCache() kullanıldığında her şarkı için cache increment yapılıyordu.
İlk erişimde cache NULL olduğu için getCachedCount() tüm şarkıları hesaplıyordu → üzerine incrementler ekleniyor.
Gerçek: 62 şarkı, 15722 sn Cache: 62 şarkı, 15950 sn (228 sn fazla)
Batch insert + tek seferde recalculate
$playlist->songs()->attach($songsToAttach); $playlist->recalculateCachedCounts();
Şarkılar hard delete edildiğinde pivot tablosundaki kayıtlar orphan kalıyordu. Playlist cache'leri güncellenmiyordu.
Playlist (ID: 27): - Pivot: 103 referans - Songs: 62 şarkı - Orphan: 41 kayıt ❌
Song model'de forceDeleting event listener
static::forceDeleting(function($song) {
// 1. Pivot temizle
// 2. Playlist cache'leri recalculate
});
Orphan şarkı (silinmiş) playlist'ten çıkarılmaya çalışıldığında Song::find() NULL döner.
Metod erken return yapar → Pivot'tan çıkarılmaz, cache güncellenmez.
if (!$songModel) {
return; // ← BUG: Pivot silinmez!
}
$this->songs()->detach($songModel->song_id);
Şarkı bulunamazsa bile:
// Pivot'tan direkt çıkar $this->songs()->detach($songId); // Cache'i yeniden hesapla $this->recalculateCachedCounts();
Orijinal: 4:33:43 (66 şarkı - cache ESKİ) Şarkı sil: 4:33:43 (65 şarkı pivot, cache YANLIŞŞ) Kopya: 4:18:42 (61 şarkı - cache DOĞRU ✓)
v3 Fix sonrası: Şarkı silme → Cache otomatik güncellenir → Kopya doğru süre gösterir
Modules/Muzibu/App/Services/PlaylistService.php
Modules/Muzibu/App/Http/Livewire/Admin/PlaylistComponent.php
Modules/Muzibu/resources/views/admin/livewire/playlist-component.blade.php
Modules/Muzibu/App/Models/Song.php
Modules/Muzibu/App/Models/Playlist.php
public function detachSongWithCache($song): void { $songModel = $song instanceof Song ? $song : Song::find($song); // ❌ BUG: Orphan şarkı için NULL döner, metod return yapar if (!$songModel) { return; // Pivot silinmez! Cache güncellenmez! } // Pivot'tan çıkar $this->songs()->detach($songModel->song_id); // Cache güncelle (increment/decrement) if ($songModel->is_active) { $this->decrementCachedCount('songs_count'); $this->decrementCachedCount('total_duration', (int) $songModel->duration); } }
public function detachSongWithCache($song): void { // ✓ Song ID'yi al (model veya ID) $songId = $song instanceof Song ? $song->song_id : $song; // ✓ Orphan olsa bile pivot'tan çıkar $this->songs()->detach($songId); // ✓ Cache'i tamamen yeniden hesapla (increment/decrement değil!) // Böylece orphan kayıtlar da düzgün temizlenir $this->recalculateCachedCounts(); }
Playlist kopyalama özelliği tamamen stabil ve kullanıma hazır.