Laravel 5.4中获取关联表最新关联数据的预加载问题
解决Laravel一对多关联获取每条父模型最新子记录的问题
这个问题我之前也碰到过,咱们来一步步拆解解决它~
为什么你的代码只返回第一条关联记录?
你原来的查询里,在with的闭包中直接调用first(),这个操作是对整个关联表集合执行排序后取第一条,而不是为每一条purchase单独获取它对应的最新历史记录。所以最终只有第一条purchase能拿到关联数据,其他的都没有匹配结果。
解决方案1:定义专属的hasOne关联(推荐)
最优雅的方式是在Purchases模型里新增一个hasOne类型的关联,专门用来获取该采购记录的最新历史:
// Purchases.php 模型文件 public function latestAccountsPurchaseHistory() { // 假设关联外键是purchase_id,按id倒序取最新的一条 return $this->hasOne(AccountsPurchaseHistory::class, 'purchase_id')->latest('id'); }
然后查询的时候直接调用这个关联即可:
$purchases = Purchases::with('latestAccountsPurchaseHistory') ->where('status', 'extended') ->orderBy('id', 'DESC') ->get();
这样每条status为extended的purchase都会带上自己对应的最新历史记录,而且这个关联可以在其他地方复用,代码更整洁。
解决方案2:使用子查询过滤关联记录
如果不想新增模型关联,也可以在with的闭包里用子查询筛选出每个purchase对应的最大id的历史记录:
use Illuminate\Support\Facades\DB; $purchases = Purchases::with(['accounts_purchase_histories' => function ($query) { $query->whereIn('id', function ($subQuery) { $subQuery->select(DB::raw('MAX(id)')) ->from('accounts_purchase_histories') ->groupBy('purchase_id'); }); }]) ->where('status', 'extended') ->orderBy('id', 'DESC') ->get();
这里通过子查询先找出每个purchase_id对应的最大历史记录id,再用这些id过滤关联数据,确保每条purchase只拿到自己的最新历史。
小提醒
注意你的关联名称accounts_purchase_historie应该是复数形式accounts_purchase_histories,可能是笔误,修正后能避免不必要的错误哦~
内容的提问来源于stack exchange,提问作者Mutasim Fuad
相关产品推荐
相关产品推荐

