如何为Laravel Eloquent创建Scope筛选与静态值列表相交的模型?
实现筛选数组字段与有效值列表有交集的模型Scope
当然可以创建这样的查询Scope,核心是利用数据库的JSON查询能力(Laravel的数组字段实际存储为JSON格式),直接在数据库层面完成交集判断,避免加载所有模型后再用PHP处理。
步骤1:确认模型字段的数组转换配置
先在你的模型里确保types字段已配置数组类型转换:
class YourModel extends Model { protected $casts = [ 'types' => 'array', ]; }
步骤2:添加本地查询Scope
在模型中定义本地Scope,支持自定义有效值列表:
public function scopeHasValidType($query, array $valid = ['one', 'two']) { // 空有效值列表直接返回无结果 if (empty($valid)) { return $query->whereRaw('1 = 0'); } // MySQL 8.0+ 推荐写法:用JSON_CONTAINS_ANY判断数组交集 $placeholders = implode(', ', array_fill(0, count($valid), '?')); return $query->whereRaw("JSON_CONTAINS_ANY(types, JSON_ARRAY($placeholders))", $valid); // 兼容MySQL 5.x的备选写法(用JSON_SEARCH检查是否存在匹配值) // $conditions = collect($valid)->map(fn($val) => "JSON_SEARCH(types, 'one', ?) IS NOT NULL")->implode(' OR '); // return $query->whereRaw($conditions, $valid); }
步骤3:使用Scope筛选模型
在业务代码中直接调用这个Scope即可:
// 使用默认有效值列表筛选 $validModels = YourModel::hasValidType()->get(); // 自定义有效值列表 $customValid = ['three', 'four']; $customValidModels = YourModel::hasValidType($customValid)->get();
其他数据库适配
如果使用PostgreSQL,可替换Scope内的查询逻辑:
// PostgreSQL 写法:利用数组交集操作符&& return $query->whereRaw("types && ARRAY[?]::text[]", [$valid]);
内容的提问来源于stack exchange,提问作者wivku
相关产品推荐
相关产品推荐

