Laravel Eloquent同查询混用where/orWhere/find返回异常如何解决?
问题根因
你遇到的非预期结果是SQL逻辑运算符优先级导致的:SQL中AND优先级高于OR,你写的原始Eloquent代码生成的SQL实际执行逻辑等价于:
SELECT * FROM links WHERE user_id = 1 OR (user_ip = '127.0.0.1' AND id = 53) LIMIT 1
只要存在user_id = 1的记录,不管后面的id条件是否匹配,都会优先返回第一条符合user_id=1的记录,也就是你遇到的始终返回id为51的记录的问题。
修正后的代码
你需要用参数分组把user_id和user_ip的OR条件包裹起来,再和id条件做AND查询,代码如下:
$link = Link::query() ->where(function ($query) { $query->where('user_id', Auth::id()) ->orWhere('user_ip', request()->ip()); }) ->with('clicks') ->findOrFail($id);
修改后生成的SQL就会和你预期的一致,自动给OR条件加上括号:
SELECT * FROM links WHERE (user_id = 1 OR user_ip = '127.0.0.1') AND id = 53 LIMIT 1
调试小技巧
如果后续遇到Eloquent生成SQL不符合预期的情况,可以临时把findOrFail($id)换成toSql()打印生成的SQL语句,快速定位逻辑问题:
dd( Link::query() ->where(function ($query) { $query->where('user_id', Auth::id()) ->orWhere('user_ip', request()->ip()); }) ->toSql() );
内容的提问来源于stack exchange,提问作者Tamim Ikbal
相关产品推荐
相关产品推荐

