Hey guys what's the best way to query a many to many relationship existence?
I have this Playlist class that has many tracks through a pivot table. The inverse is true for the Track class as well. I want to query a list of playlists that have at least one track.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Playlist extends BaseModel
{
protected $guarded = [];
public function scopeHasTracks($query)
{
return $query->has('tracks');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function tracks(): BelongsToMany
{
return $this->belongsToMany(Track::class)
->withTimestamps()
->orderBy('playlist_track.created_at');
}
}```
I've tried with `has` but it's not working. It keeps saying:
Illuminate/Database/QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'created_at' in order clause is ambiguous (SQL: select * from playlists where exists (select * from tracks inner join playlist_track on tracks.id = playlist_track.track_id where playlists.id = playlist_track.playlist_id order by created_at desc, created_at desc) order by created_at desc limit 1)'
It works without it. But I'm pulling the list of playlists from the API through an app. I don't want to display empty playlist. So that's why I need this option.
<?php
namespace App\Models;
use Laravel\Scout\Searchable;
use App\Traits\HelperTrait;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Storage;
class Track extends BaseModel
{
use Searchable;
use HelperTrait;
private $default_poster_url = "https://img-storage-prod.mp3pam.com/placeholders/track-placeholder.jpg";
protected $guarded = [];
protected $casts = [
'allowDownload' => 'boolean',
];
public function playlists(): BelongsToMany
{
return $this->belongsToMany(Playlist::class)
->withTimestamps()
->orderBy('playlist_track.created_at');
}
public function artist(): BelongsTo
{
return $this->belongsTo(Artist::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function genre(): BelongsTo
{
return $this->belongsTo(Genre::class);
}
public function album(): BelongsTo
{
return $this->belongsTo(Album::class);
}
public function setDetailAttribute($detail)
{
$this->attributes['detail'] = nl2br($detail);
}
public function setLyricsAttribute($lyrics)
{
$this->attributes['lyrics'] = nl2br($lyrics);
}
public function scopeByHash($query, $hash)
{
return $query->where('hash', $hash);
}
public function scopeByGenre($query, $genre_slug)
{
$genre = Genre::whereSlug($genre_slug)->first();
$query->where('genre_id', $genre->id);
}
public function scopeRand($query)
{
$query->orderByRaw('RAND()');
}
public function scopeRelated($query, $obj)
{
$query
->whereGenreId($obj->genre_id)
->where('id', '!=', $obj->id)
->orderByRaw('RAND()'); // get random rows from the DB
// ->published()
}
public function scopeLastMonth($query)
{
$today = Carbon::today();
$lastMonth = Carbon::today()->subMonth();
$query
->where('created_at', '<', $today)
->where('created_at', '>', $lastMonth);
}
public function scopePopular($query)
{
$query
->orderBy('download_count', 'desc')
->orderBy('play_count', 'desc');
}
public function scopeFeatured($query)
{
$query->whereFeatured(1);
}
public function scopePublished($query)
{
$query->wherePublish(1);
}
public function isPublished()
{
return $this->publish === 1;
}
public function scopeByPlay($query)
{
$query->orderBy('play_count', 'desc');
}
public function toSearchableArray()
{
extract($this->toArray());
return compact('id', 'title', 'detail', 'lyrics');
}
}