Php 关于关系的雄辩的查询范围
我有两种型号,App\Song(belongsTo App\Host)和App\Host(有许多App\Song) 我的控制器中有以下查询:Php 关于关系的雄辩的查询范围,php,laravel,eloquent,Php,Laravel,Eloquent,我有两种型号,App\Song(belongsTo App\Host)和App\Host(有许多App\Song) 我的控制器中有以下查询: $songs = Song::whereHas('host', function($query) { $query->where('skip_threshold', '>', \DB::raw('songs.attempts')) ->where('active'
$songs = Song::whereHas('host', function($query) {
$query->where('skip_threshold', '>', \DB::raw('songs.attempts'))
->where('active', 1);
})
->whereNull('downloaded')
->get();
为了可重用性,我想将其转换为一个查询范围
我对雄辩很陌生,所以我不确定这是正确的方法,因为它的两个模型没有返回任何结果(应该有)
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');
}
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');
}
您应该将作用域放入它们所属的模型中。查看您的初始查询范围
scopeligable
和scopeActiveHost
属于Host
模型,因此您应该将它们移动到Host
模型中,然后您可以使用如下范围使用您的查询:
$songs = Song::whereHas('host', function($query) {
$query->eligable()->activeHost();
})->inDownloadedQueue()->get();
正如注释中已经指出的,您应该将return
添加到每个范围中,以便它们可以按预期使用
编辑
如果您想缩短使用时间,可以在Song
model中创建新关系:
public function activeHost()
{
return $this->belongsTo(Host:class)->eligable()->activeHost();
}
现在,你可以写:
$songs = Song::whereHas('activeHost')->inDownloadedQueue()->get();
我认为你对两种型号的看法是错误的。我认为这应该行得通 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');
}
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');
}
用法
$songs = Song::eligable(true)->inDownloadQueue()->get();
控制器中用于调用这些查询范围的代码是什么?(没有返回结果?
Song::eligable()->activehost()->indownloadqueue()->get()
在所有作用域中都应该有return
<代码>返回$query->whereNull('下载')代码>。作用域应始终返回查询生成器实例。我已经更新了返回查询的作用域,但是仍然没有返回任何数据。您可能需要直接查看sql。您是否安装了DebugBar?如果没有,请在查询调用之前尝试此操作\事件::侦听('light.query',函数($query,$params,$time,$conn){dd(数组($query,$params,$time,$conn));});这就像预期的那样工作,但是这仍然需要三行代码,为了简单起见,在代码中有没有一种方法可以将其缩短为一行?嗨,Marcin,我现在正在使用代码,但它似乎没有按照预期工作。我已尝试使用->toSql()
函数调试并生成以下SQL:从存在的“歌曲”中选择*(从“歌曲”所在的“主机”中选择*。“主机id”=“主机”。.id”和“跳过阈值”>歌曲。尝试次数和“活动”=?)和“下载”为空
。有什么想法吗?