I have two models, App\Song (belongsTo App\Host) and App\Host (hasMany App\Song).
I have the following query in my Controller:
$songs = Song::whereHas('host', function($query) {
$query->where('skip_threshold', '>', \DB::raw('songs.attempts'))
->where('active', 1);
})
->whereNull('downloaded')
->get();
For reusability I would like to turn into a query scope(s).
I'm quite new to Eloquent so I'm not sure this is the correct way to do this being that its two Models as its not returning any results (where there should be).
Song.php
public function scopeEligable($query)
{
$query->where('skip_threshold', '>', \DB::raw('songs.attempts'));
}
public function scopeActiveHost($query)
{
$query->where('active', 1);
}
public function scopeInDownloadQueue($query)
{
$query->whereNull('downloaded');
}
You should put scopes into Models they belong to. Looking at your initial query scopes scopeEligable
and scopeActiveHost
belongs to Host
model, so you should move them into Host
model and then you'll be able to use your query using scopes like this:
$songs = Song::whereHas('host', function($query) {
$query->eligable()->activeHost();
})->inDownloadedQueue()->get();
and as already pointed in comment you should add return
to each scope so they could be used as they intended.
EDIT
If you would like to make using it shorter, you could create new relationship in Song
model:
public function activeHost()
{
return $this->belongsTo(Host:class)->eligable()->activeHost();
}
so now, you could write:
$songs = Song::whereHas('activeHost')->inDownloadedQueue()->get();
I think you're mistaken about 2 models. I think this should work
Song.php
public function scopeEligable($query, $active) {
return $query->whereHas('host', function($q) {
$q->where('skip_threshold', '>', \DB::raw('songs.attempts'))->where('active', $active);
})
}
public function scopeInDownloadQueue($query)
{
$query->whereNull('downloaded');
}
Usage
$songs = Song::eligable(true)->inDownloadQueue()->get();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With