You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中重写last()方法?解决关联查询最新记录不一致问题

Laravel一对多关联中按ID而非created_at获取最新余额记录

现有关联代码与问题

我在User和UserBalances模型间建立了一对多关联:

User模型代码

public function user_balances(){
    return $this->hasMany(UserBalances::class);
}

UserBalances模型代码(注意:此处存在笔误,已修正)

原代码中belongsTo关联的模型写错了,正确写法应为:

public function user(){
    return $this->belongsTo(User::class);
}

当前获取方式与问题

我之前通过以下方式获取用户的最后一条余额记录:

$user = User::first();
$user->user_balances->last()

但由于余额记录生成速度快,多条记录可能出现相同的created_at时间戳,导致last()方法(依赖集合默认排序)无法稳定获取到真正最新的记录(ID最大的那条)。

我也尝试过直接查询的方式:

$user = User::first();
$user_balance_last = UserBalance::where('user_id', $user->id)->latest('id')->first();

解决方案

1. 新增专属关联获取最新记录(推荐)

在User模型中新增一个hasOne关联,利用Laravel的latestOfMany方法直接关联到最新的余额记录,指定按id排序:

public function latest_user_balance(){
    return $this->hasOne(UserBalances::class)->latestOfMany('id');
}

使用时直接调用关联即可,无需额外处理:

$user = User::first();
$latestBalance = $user->latest_user_balance;

这种方式是Laravel官方推荐的,仅查询单条记录,性能最优且结果稳定。

2. 修改原有关联的默认排序

如果需要保留原有的user_balances关联集合,可在关联中设置默认按id升序排序,这样last()就能拿到ID最大的记录:

public function user_balances(){
    return $this->hasMany(UserBalances::class)->orderBy('id', 'asc');
}

使用方式不变:

$user = User::first();
$latestBalance = $user->user_balances->last();

注意:此方式会加载该用户的所有余额记录,数据量大时性能较差。

3. 优化直接查询的写法

你之前尝试的直接查询可以优化为关联查询,无需手动拼接user_id条件:

$user = User::first();
$latestBalance = $user->user_balances()->latest('id')->first();

这种写法更符合Laravel关联查询的规范,同时保证只查询单条最新记录。


内容的提问来源于stack exchange,提问作者randy-ar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 07:52:43