如何在Laravel Lighthouse标准模型搜索中添加后端统一过滤条件
方案1:使用Laravel全局作用域(推荐,适配所有场景包括关联查询)
该方案无需修改现有GraphQL schema,也不需要自定义解析器,所有通过Product模型发起的查询(包括Lighthouse内置的@find、@paginate、关联关系预加载)都会自动带上exist = true的过滤条件:
打开你的Product.php模型文件,添加全局作用域注册逻辑即可:
<?php namespace App\Components\Product; use App\Components\Tag\Tag; use App\Components\File\File; use App\Core\Model\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Product extends Model { protected $fillable = [ 'title', 'description', 'tags', 'view_id', 'price', 'discount', 'quantity', 'exist' ]; // 新增启动方法注册全局作用域 protected static function booted() { parent::booted(); // 全局添加exist=true的查询条件 static::addGlobalScope('filterExist', function ($query) { $query->where('exist', true); }); } /** * @return BelongsToMany */ public function tags(): BelongsToMany { return $this->belongsToMany(Tag::class); } /** * @return BelongsTo */ public function view(): BelongsTo { return $this->belongsTo(File::class); } }
如果Tag、File等其他关联模型也有相同的软删标记字段,给对应模型也添加同样的全局作用域即可,关联查询时会自动触发过滤。
如果后续有特殊场景需要查询已被标记为删除的记录,可以手动移除该作用域:
// 单个查询移除全局作用域 $allProducts = Product::withoutGlobalScope('filterExist')->get();
方案2:使用Lighthouse内置@where指令(仅针对单独查询配置)
如果不需要全局生效,只需要给当前公开的GraphQL查询加过滤,可以直接修改你的graphql.schema,给查询字段加@where指令:
type Query { products: [Product!]! @paginate @where(key: "exist", value: true) product(id: ID @eq): Product @find @where(key: "exist", value: true) }
该方案的缺点是需要手动给所有涉及Product查询的字段、关联字段加指令,不适用于需要全局过滤的场景。
内容的提问来源于stack exchange,提问作者wowandy
相关产品推荐
相关产品推荐

