Laravel Spatie 按关系最后一个元素自定义过滤器
Laravel Spatie Custom Filter by Relation Last Element
我有一个动物模型。动物关系检查和疾病模型。我需要过滤生病的动物。
考试模式有disease_id。如果最后一个检查对象 disease_id 不等于 null,则该动物生病了。我正在尝试使用 spatie 过滤器对其进行过滤。
这是我的自定义过滤器代码:
这必须按上次检查数据过滤。但是通过所有检查数据过滤。
<?php
use Spatie\QueryBuilder\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
class SickAnimalsFilter implements Filter
{
public function __invoke(Builder $query, $value, string $property)
{
$query->whereHas('examinations', function($q) {
$q->orderBy('created_at', 'DESC')->limit(1)->where('disease_id', '!=', null);
});
}
}
示例数据:
这应该包含在过滤中。这只动物现在病了。
"examinations": [
{
"id": 1,
"animal_id": 1,
"disease_id": 1
"created_at": "2022-01-28T09:24:46.000000Z",
"updated_at": "2022-01-28T09:24:46.000000Z",
}
]
这不应包含在筛选中。这只动物以前生病了,现在好了。
"examinations": [
{
"id": 1,
"animal_id": 1,
"disease_id": 1
"created_at": "2022-01-28T09:24:46.000000Z",
"updated_at": "2022-01-28T09:24:46.000000Z",
},
{
"id": 2,
"animal_id": 1,
"disease_id": null
"created_at": "2022-01-30T15:29:00.000000Z",
"updated_at": "2022-01-30T15:29:00.000000Z",
}
]
我解决了这个问题:
<?php
use App\Models\Examination;
use Spatie\QueryBuilder\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
class SickAnimalsFilter implements Filter
{
public function __invoke(Builder $query, $value, string $property)
{
$examinationIds = $query->withMax('examinations', 'id')->get()->pluck('examinations_max_id');
$animalIds = Examination::query()->groupBy('animal_id', 'id')->get()->whereIn('id', $examinationIds)->where('disease_id', '!=', null)->pluck('animal_id');
$query->whereIn('id', $animalIds);
}
}
我得到了每只动物的最后一次检查 ID 并写信给 $examinationIds
。
并使用 $examinationIds
过滤考试。
过滤后使用 pluck('animal_id')
.
获取动物 ID
然后用$animalIds
过滤$query
。
我有一个动物模型。动物关系检查和疾病模型。我需要过滤生病的动物。
考试模式有disease_id。如果最后一个检查对象 disease_id 不等于 null,则该动物生病了。我正在尝试使用 spatie 过滤器对其进行过滤。
这是我的自定义过滤器代码:
这必须按上次检查数据过滤。但是通过所有检查数据过滤。
<?php
use Spatie\QueryBuilder\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
class SickAnimalsFilter implements Filter
{
public function __invoke(Builder $query, $value, string $property)
{
$query->whereHas('examinations', function($q) {
$q->orderBy('created_at', 'DESC')->limit(1)->where('disease_id', '!=', null);
});
}
}
示例数据:
这应该包含在过滤中。这只动物现在病了。
"examinations": [
{
"id": 1,
"animal_id": 1,
"disease_id": 1
"created_at": "2022-01-28T09:24:46.000000Z",
"updated_at": "2022-01-28T09:24:46.000000Z",
}
]
这不应包含在筛选中。这只动物以前生病了,现在好了。
"examinations": [
{
"id": 1,
"animal_id": 1,
"disease_id": 1
"created_at": "2022-01-28T09:24:46.000000Z",
"updated_at": "2022-01-28T09:24:46.000000Z",
},
{
"id": 2,
"animal_id": 1,
"disease_id": null
"created_at": "2022-01-30T15:29:00.000000Z",
"updated_at": "2022-01-30T15:29:00.000000Z",
}
]
我解决了这个问题:
<?php
use App\Models\Examination;
use Spatie\QueryBuilder\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
class SickAnimalsFilter implements Filter
{
public function __invoke(Builder $query, $value, string $property)
{
$examinationIds = $query->withMax('examinations', 'id')->get()->pluck('examinations_max_id');
$animalIds = Examination::query()->groupBy('animal_id', 'id')->get()->whereIn('id', $examinationIds)->where('disease_id', '!=', null)->pluck('animal_id');
$query->whereIn('id', $animalIds);
}
}
我得到了每只动物的最后一次检查 ID 并写信给 $examinationIds
。
并使用 $examinationIds
过滤考试。
过滤后使用 pluck('animal_id')
.
然后用$animalIds
过滤$query
。