美好的一天,
我在这里有点卡在使用 Laravel 范围和雄辩的多态一对多关系获取最新项目时。
鉴于:
- 我使用的是最新版本的 Laravel 6.x。
- 我有两种型号:
Website
和Status
。 Status
模型是可重复使用的,可以与其他模型一起使用。- 每个网站都有多种状态。
- 每次更改状态时,都会在数据库中创建一个新记录。
- 活动网站状态是数据库中的最新状态。
网站型号:
class Website extends Model
{
public function statuses()
{
return $this->morphMany(Statuses::class, 'stateable');
}
public function scopePending($query)
{
return $query->whereHas('statuses', function ($query) {
$query->getByStatusCode('pending');
});
}
}
状态模型:
class Statuses extends Model
{
public function stateable()
{
return $this->morphTo();
}
public function scopeGetByStatusCode($query, $statusCode)
{
return $query->where('status_code', $statusCode)->latest()->limit(1);
}
}
问题是,当我打电话时:
Website::pending()->get();
pending()
范围将返回曾经分配过pending
状态的所有网站,而不是当前具有活动pending
状态(例如最新状态(的网站。
下面是随DB::getQueryLog()
返回的查询
select * from `websites`
where exists
(
select * from `statuses`
where `websites`.`id` = `statuses`.`stateable_id`
and `statuses`.`stateable_type` = "App\Models\Website"
and `status_code` = 'pending'
order by `created_at` desc limit 1
)
and `websites`.`deleted_at` is null
使用具有多态一对多关系的范围获取pending
网站的正确方法是什么?
这里描述了类似的问题:https://laracasts.com/discuss/channels/eloquent/polymorphic-relations-and-scope
谢谢。
好的,在做了一些研究之后,我偶然发现了这篇文章:https://nullthoughts.com/development/2019/10/08/dynamic-scope-on-latest-relationship-in-laravel/
解决方案结果非常雄辩(对不起,双关语不好(:
protected function scopePending($query)
{
return $query->whereHas('statuses', function ($query) {
$query->where('id', function ($sub) {
$sub->from('statuses')
->selectRaw('max(id)')
->whereColumn('statuses.stateable_id', 'websites.id');
})->where('status_code', 'pending');
});
}