Laravel Eloquent JSON字段筛选问题:用户可查看记录查询失败求助
排查你的Eloquent JSON查询问题
首先得点出你原代码的核心问题:你把JSON数组当成JSON对象来处理啦!allowed和blocked存储的是用户ID数组,但你用allowed->$user_id这种语法是在查找JSON对象里的键,这完全不对路,自然查不出正确结果。
原代码的问题点
- 对于JSON数组,
allowed->$user_id这种写法完全无效,因为数组是值的集合而非键值对结构,Laravel无法识别你要检查数组是否包含某个ID。 - 虽然
allowed为空的判断逻辑是对的,但和错误的数组包含判断组合后,整体查询逻辑直接失效。
正确的实现方式
Laravel专门提供了处理JSON数组的whereJsonContains方法,正好适配你的场景。我们需要调整查询逻辑为:
- 满足以下任一条件:
allowed字段为空(意味着允许所有用户查看)allowed数组中包含当前user_id
- 同时满足:
blocked字段为空,或者blocked数组中不包含当前user_id
对应的Eloquent代码如下:
Records::where(function ($query) use ($user_id) { $query->whereNull('allowed') ->orWhereJsonContains('allowed', $user_id); }) ->where(function ($query) use ($user_id) { $query->whereNull('blocked') ->orWhereJsonDoesntContain('blocked', $user_id); }) ->get();
补充说明
whereJsonContains:检查JSON数组是否包含指定值,Laravel会自动转换为对应数据库的SQL函数(比如MySQL的JSON_CONTAINS)。whereJsonDoesntContain:Laravel 5.7及以上版本支持的方法,用来检查JSON数组不包含指定值。如果你的Laravel版本较低,可以用原生SQL替代这部分逻辑:->whereRaw('NOT JSON_CONTAINS(blocked, ?)', [$user_id])- 务必把
user_id作为参数传入,避免SQL注入风险。
内容的提问来源于stack exchange,提问作者Alex Lomov
相关产品推荐
相关产品推荐

