'string', 'order' => 'integer', 'is_active' => 'boolean', ]; protected $attributes = [ 'type' => 'public', // Default value ]; // Relation to user (optional) public function user() { return $this->belongsTo(User::class); } public function playlist(): BelongsTo { return $this->belongsTo(MusicPlaylist::class, 'playlist_id'); } public function tags(): BelongsToMany { return $this->belongsToMany(Tag::class, 'music_tags'); } protected $appends = ['url', 'image_url' , 'average_rating', 'user_rating', 'comments_count']; // New rating and comment relationships public function ratings(): MorphMany { return $this->morphMany(Rating::class, 'rateable'); } public function comments(): MorphMany { return $this->morphMany(Comment::class, 'commentable'); } // Accessors for ratings public function getAverageRatingAttribute(): float { return round($this->ratings()->avg('stars'), 1); } public function getUserRatingAttribute(): ?int { if (!auth()->check()) return null; return $this->ratings() ->where('user_id', auth()->id()) ->value('stars'); } public function getCommentsCountAttribute(): int { return $this->comments()->count(); } // Accessor for full URL public function getUrlAttribute() { return asset('storage/' . $this->file_path); } public function image() { return $this->belongsTo(Image::class, 'image_id'); } public function getImageUrlAttribute() { return $this->image ? asset('storage/' . $this->image->path) : null; } }