Вы можете переписать ваш запрос как левое соединение, чтобы получить те же результаты
select a.*
from part_histories a
left join part_histories b on a.part_id = b.part_id
and a.created_at < b.created_at
where b.part_id is null
, и я думаю, что вы можете легко преобразовать запрос выше в своей области, например,
public function scopeWithLatestStatus($query)
{
return $query->leftJoin('part_histories as b', function ($join) {
$join->on('a.part_id', '=', 'b.part_id')
->where('a.created_at', '<', 'b.created_at');
})
->whereNull('b.part_id')
->from('part_histories as a')
->select('a.*');
}
Laravel Eloquent выбрать все строки с максимальным созданным_ат
Laravel - Получить последнюю запись каждого типа UID
Laravel Eloquent группы по самой последней записи
Редактировать, используя указанный выше запрос как отношение has
. Чтобы получить новейшую историю для каждой детали, вы можете определить отношение hasOne
, например
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class Part extends Model
{
public function latest_history()
{
return $this->hasOne(\App\Models\PartHistory::class, 'part_id')
->leftJoin('part_histories as p1', function ($join) {
$join->on('part_histories.part_id', '=', 'p1.part_id')
->whereRaw(DB::raw('part_histories.created_at < p1.created_at'));
})->whereNull('p1.part_id')
->select('part_histories.*');
}
}
, а затем загрузить деталис их новейшей историей вы можете загружать вышеуказанное отображение как
$parts = Part::with('latest_history')->get();
У вас будет список деталей вместе с новейшей историей как
Array
(
[0] => Array
(
[id] => 1
[title] => P1
[latest_history] => Array
(
[id] => 6
[created_at] => 2018-06-16 08:25:10
[status] => 1
[part_id] => 1
)
)
....
)