✅ Tamamlandı 08 Ocak 2026

🔗 Polymorphic İlişkileri Düzeltme

Radio ve Sector sayfaları için playlistable polymorphic ilişkilerinin düzeltilmesi

📝 Basit Anlatım (Herkes İçin)

Müzik platformunda Radyolar ve Sektörler sayfaları boş görünüyordu. Database'de veriler vardı (122 radyo, 23 sektör, 2152 playlist ilişkisi) ama sayfalar gösterilmiyordu.

Neden? Sistem radyo/sektörlerin playlist'lerini okuyamıyordu çünkü ilişki tanımı yanlıştı.

Çözüm: İlişki tanımını düzelttik. Artık:

🔧 Teknik Detaylar (Geliştiriciler İçin)

📊 Database Durumu

muzibu_playlistables tablosu: 2152 kayıt ├── Radio ilişkileri: 361 kayıt (playlistable_type='Radio') ├── Sector ilişkileri: 1790 kayıt (playlistable_type='Sector') └── Genre ilişkileri: 1 kayıt (playlistable_type='Genre') muzibu_radios: 122 aktif kayıt muzibu_sectors: 23 aktif kayıt

🐛 Bulunan Hatalar

HATA 1

HasPlaylistDistribution Trait - Yanlış Method

HasPlaylistDistribution.php line 30'da morphedByMany kullanılmıştı.

// ❌ YANLIŞ (Inverse relationship) return $this->morphedByMany( Playlist::class, 'playlistable', 'muzibu_playlistables', 'playlistable_id', 'playlist_id' );

Sorun: morphedByMany ters ilişki içindir (Playlist → entities). Radyo/Sektör → Playlists ilişkisi için morphToMany kullanılmalıydı.

HATA 2

Genre.php - Method Duplikasyonu

Genre.php line 107-118'de manuel playlists() methodu tanımlıydı ama line 17'de HasPlaylistDistribution trait zaten kullanılıyordu.

// ❌ DUPLIKASYON (Trait zaten playlists() tanımlıyor) class Genre extends BaseModel { use HasPlaylistDistribution; // Trait içinde playlists() var public function playlists() { // Manuel de tanımlanmış! return $this->morphToMany(...); } }

Sorun: PHP'de class method trait method'unu override eder. Genre'de manuel method vardı, trait method kullanılmıyordu. Radio ve Sector'da böyle bir sorun yoktu.

🔨 Yapılan Düzeltmeler

FIX 1

HasPlaylistDistribution Trait Düzeltildi

Modules/Muzibu/app/Traits/HasPlaylistDistribution.php line 28-39

// ✅ DOĞRU (Direct relationship) public function playlists(): MorphToMany { return $this->morphToMany( // morphedByMany → morphToMany Playlist::class, 'playlistable', 'muzibu_playlistables', 'playlistable_id', 'playlist_id', $this->getKeyName(), // genre_id, radio_id, sector_id 'playlist_id' )->withPivot('position')->withTimestamps()->orderBy('muzibu_playlistables.position'); }
FIX 2

Genre.php Duplikasyonu Kaldırıldı

Modules/Muzibu/app/Models/Genre.php line 103-104

// ❌ Silindi (Duplikasyon) public function playlists() { return $this->morphToMany(...); } // ✅ Eklendi (Açıklama) // playlists() metodu artık HasPlaylistDistribution trait'inden geliyor // Eski tablo: muzibu_playlist_genre → Yeni tablo: muzibu_playlistables

Radio ve Sector modellerinde zaten böyle bir yorum vardı, Genre'ye de eklendi.

KONTROL

AppServiceProvider Morph Map

app/Providers/AppServiceProvider.php line 114-127

// ✅ Morph map ZATEN TANIMLIYDI (değişiklik yapılmadı) \Illuminate\Database\Eloquent\Relations\Relation::morphMap([ 'User' => \App\Models\User::class, 'Genre' => \Modules\Muzibu\App\Models\Genre::class, 'Radio' => \Modules\Muzibu\App\Models\Radio::class, 'Sector' => \Modules\Muzibu\App\Models\Sector::class, 'Corporate' => \Modules\Muzibu\App\Models\MuzibuCorporateAccount::class, 'Playlist' => \Modules\Muzibu\App\Models\Playlist::class, 'Album' => \Modules\Muzibu\App\Models\Album::class, 'Artist' => \Modules\Muzibu\App\Models\Artist::class, 'Song' => \Modules\Muzibu\App\Models\Song::class, ]);

Database'de playlistable_type='Radio' olarak saklanan değerler, morph map sayesinde \Modules\Muzibu\App\Models\Radio::class olarak çözümleniyor.

✅ Test Sonuçları

🎵 Radios Page

URL: /radios
Radyo sayısı: 122
Durum: ✅ Çalışıyor
Örnek radyolar:
- Radio Acoustic - Radio Ala - Radio Blues (8 playlist)

🏢 Sectors Page

URL: /sectors
Sektör sayısı: 22
Durum: ✅ Çalışıyor
Örnek sektörler:
- Cafe (177 playlist) - Bar - Otel - Gym

🧪 Backend Test (Tinker)

// Radio test $radio = Radio::first(); $radio->playlists()->count(); // 8 playlist ✅ // Sector test $sector = Sector::first(); $sector->playlists()->count(); // 177 playlist ✅ // Genre test $genre = Genre::first(); $genre->playlists()->count(); // 1 playlist ✅ // Controller filter test Radio::whereHas('playlists', fn($q) => $q->where('is_active', 1))->count(); // 122 radyo ✅ (whereHas artık çalışıyor!) Sector::whereHas('playlists', fn($q) => $q->where('is_active', 1))->count(); // 22 sektör ✅

📚 Polymorphic İlişkiler Hakkında

Polymorphic ilişkiler, bir modelin birden fazla farklı model tipine ait olabilmesini sağlar. Müzik platformunda playlist'ler radyo, sektör veya genre'lere atanabiliyor.

🔄 İki Yönlü İlişki

Direct (morphToMany)

Radio → Playlists

$radio->playlists() // Radio'nun sahip olduğu playlist'ler

Inverse (morphedByMany)

Playlist → Radios

$playlist->radios() // Bu playlist'in atandığı radyolar

🗄️ Tablo Yapısı

-- muzibu_playlistables pivot tablosu CREATE TABLE muzibu_playlistables ( playlist_id INT, -- Playlist ID playlistable_type VARCHAR, -- 'Radio', 'Sector', 'Genre' playlistable_id INT, -- Radio/Sector/Genre ID position INT, -- Sıralama created_at, updated_at ); -- Örnek kayıt: playlist_id: 123 playlistable_type: 'Radio' ← Morph map ile çözümlenir playlistable_id: 45 ← radio_id

🎯 Morph Map

Database'de short name ('Radio') saklanıyor, Laravel bunu morph map ile full class name'e çeviriyor:

// Database'de playlistable_type = 'Radio' // Morph map çözümlemesi 'Radio' → \Modules\Muzibu\App\Models\Radio::class // Laravel query oluştururken SELECT * FROM muzibu_radios WHERE radio_id = 45

📁 İlgili Dosyalar

Modules/Muzibu/app/Traits/HasPlaylistDistribution.php
Polymorphic ilişki trait'i (morphToMany düzeltildi)
Modules/Muzibu/app/Models/Genre.php
Duplikasyon kaldırıldı (lines 103-104)
ℹ️
Modules/Muzibu/app/Models/Radio.php
Trait kullanıyor, değişiklik yapılmadı
ℹ️
Modules/Muzibu/app/Models/Sector.php
Trait kullanıyor, değişiklik yapılmadı
ℹ️
app/Providers/AppServiceProvider.php
Morph map zaten tanımlıydı (lines 114-127)
ℹ️
Modules/Muzibu/app/Http/Controllers/Front/RadioController.php
whereHas filter artık çalışıyor
ℹ️
Modules/Muzibu/app/Http/Controllers/Front/SectorController.php
whereHas filter artık çalışıyor