Personally I shouldn't let the scope call a global function but let the controller give it to the scope.
You want to add a local scope (se https://laravel.com/docs/8.x/eloquent#local-scopes ) This suspect a query builder as parameter where you add the where statements.
Here a version for the scope.
Song Model:
class Song extends Model
{
use HasFactory, Likable;
public function artist()
{
return $this->belongsTo(Artist::class, 'artist_id');
}
public function tags()
{
return $this->belongsToMany(Tag::class)->withTimestamps();
}
public function scopeByUser(\Illuminate\Database\Eloquent\Builder $query, $user)
{
if ($user->hasRole('admin')) {
return $query;
}
if (isset($user->artist)) {
return $query->where([
'isVerified' => true,
'isOutOfDate' => false,
'isBanned' => false
])->orWhere(function ($artistQuery) use ($user) {
foreach ($user->artist as $artist) {
$artistQuery->where([
'artist_id', $artist->id,
'isOutOfDate' => false,
'isBanned' => false
]);
}
});
}
return $query->where([
'isVerified' => true,
'isOutOfDate' => false,
'isBanned' => false
]);
}
}
I added a query variable to get clear what the different options where and make the code a little smaller.
SongController:
public function index(Request $request)
{
$songsQuery = $songs = Song::query()
->ByUser($request->user())
->withLikes();
if (request('tag')) {
$songsQuery = $songsQuery->whereHas('tags', function ($query) {
$tag = request('tag');
$query->where('name', $tag);
});
} elseif ($request) {
$search = $request->input('search');
$songsQuery = $songsQuery->where('title', 'LIKE', "%{$search}%")->orWhere('text', 'LIKE', "%{$search}%");
} else {
$songsQuery = $songsQuery->latest();
}
$songs = $songsQuery->get();
return view('welcome', compact('songs'));
}
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community