为什么我不能在 Eloquent 代码中使用 latest()?

Why can't I use latest() in my Eloquent code?

我遇到了一个错误 'Method Illuminate\Database\Eloquent\Collection::latest does not exist' 在我的代码的这一行

     $items=Item::select('*')
    ->orderBy('version','DESC')
    ->get()
    ->unique('name')->latest()->paginate(5);

我不太确定为什么以及应该如何更改我的代码?

latest() 是一个 Builder class 方法而不是一个 Collection class 方法见:https://laravel.com/api/8.x/Illuminate/Database/Eloquent/Builder.html#method_latest

所以在通过get()paginate()获取集合之前使用它:

$items=Item::select('*')
    ->orderBy('version','DESC')
    ->latest()
    ->get()
    ->unique('name');

对唯一值使用分页有点复杂。如果有更多同名记录,我们需要知道 select 是什么。最简单的方法是使用 distinct() 但这可能不是您需要的:

$items=Item::select('*')
    ->orderBy('version','DESC')
    ->latest()
    ->distinct()
    ->paginate(5);

另一种可能性是使用 groupBy('name') 而不是 distinct(),但是您必须仔细聚合 'name' 周围的其他列(或 select 只有 'name' 列)。示例:

$items=Item::select('name', DB::raw('MAX(version) as max_version'))
    ->orderBy('max_version','DESC')    
    ->group_by('name')
    ->paginate(5);

如果您需要更多列 selected 使用适当的聚合函数 MAX() 或 FIRST()、LAST()、AVG() 等。

获取整行(不能使用简单的'*'):

$max_version_table = Item::select('model_name', DB::raw('MAX(version) as max_version'))->groupBy('model_name');

$items = Item::select('*')->joinSub($max_version_table, 'max_version_table', function($join){
  $join->on('items.model_name','=','max_version_table.model_name');
  $join->on('items.version','=','max_version_table.max_version');
})->paginate(5);

Laravel 的 latest 方法不适用于 集合 ,它适用于 Query-Builder。所以,首先,使用 latest 方法,然后使用 paginate.

$items = Item::select('*')
     ->orderBy('version','DESC')
     ->latest()
     ->distinct()
     ->paginate(5);