Laravel 5 Eloquent查询返回集合所有模型ID均为1的问题排查
问题排查与解决方案
这个问题我之前在Laravel项目里碰到过,核心原因是多表联查时的字段名冲突导致的,咱们一步步拆解:
为什么会出现ID全为1的情况?
你的SQL用了select *,而games和game_vendors表都有id字段。在MySQL终端里,它会把两个id字段分别显示出来(比如列名都是id但对应不同表的数据),但当PHP处理查询结果时,返回的是关联数组——数组的键名是唯一的,后面的id值会直接覆盖前面的。
如果刚好所有符合条件的game_vendors记录的id都是1,那最终所有模型的id就都会被覆盖成1,这就是你看到的异常。
解决方案
方案1:明确指定字段并给冲突字段取别名
不要用select *,手动列出需要的字段,给冲突的字段(比如game_vendors.id)取别名,确保games.id是唯一的id键:
$games = DB::table('games') ->select( 'games.id as id', // 明确保留games的id作为模型的id 'games.name', 'games.description', 'game_vendors.id as vendor_id', // 给供应商id取别名 'game_vendors.name as vendor_name' // 其他你需要的字段 ) ->leftJoin('game_vendors', 'games.vendor_id', '=', 'game_vendors.id') ->where('game_vendors.name', '!=', 'some_vendor') ->whereNotIn('games.id', range(1, 12)) ->get();
方案2:用Eloquent关联查询(更符合Laravel最佳实践)
如果你的项目里已经定义了Game和GameVendor模型,推荐用Eloquent的关联查询来避免字段冲突:
首先在Game模型里定义关联:
// app/Game.php namespace App; use Illuminate\Database\Eloquent\Model; class Game extends Model { public function vendor() { return $this->belongsTo(GameVendor::class, 'vendor_id'); } }
然后用whereHas来过滤关联模型的条件:
$games = Game::whereHas('vendor', function ($query) { $query->where('name', '!=', 'some_vendor'); }) ->whereNotIn('id', range(1, 12)) ->get();
这种方式下,Eloquent会自动处理表字段的映射,不会出现字段覆盖的问题,代码也更易维护。
验证方法
你可以先在Laravel里执行DB::select(你的SQL语句),打印返回的数组,就能看到数组里的id字段已经被覆盖成game_vendors.id的值了,这就能确认问题所在。
内容的提问来源于stack exchange,提问作者vitasya
相关产品推荐
相关产品推荐

