如何在Laravel模型中预过滤数据,结合Lighthouse GraphQL排除过期课程场次
解决方案
你有两种常用的实现方案,都可以满足过滤过期场次的需求:
方案一:使用Laravel查询作用域 + Lighthouse @scope 指令(推荐)
该方案不需要修改原有请求逻辑,直接在关联查询层面自动过滤过期数据,同时可以复⽤Lighthouse内置的排序、分页等能⼒:
- 在Instance模型中添加本地查询作用域:
// app/Models/Instance.php public function scopeActive($query) { // 过滤开始时间小于当前时间的过期场次 return $query->where('start_date', '>=', now()); }
- 修改GraphQL Schema的instances字段定义,添加
@scope指令调用作用域:
type Course{ id: ID! title: String! instances( "Order by date" orderBy: [OrderByClause!] @orderBy ): [Instance!] @hasMany @scope(name: "active") }
配置完成后所有查询course下的instances时会自动添加过期过滤逻辑,原有排序规则完全不受影响。如果后续需要兼容查询历史场次的需求,还可以扩展参数控制过滤开关:
type Course{ id: ID! title: String! instances( "Order by date" orderBy: [OrderByClause!] @orderBy, "是否包含过期场次,默认不包含" includeExpired: Boolean @default(value: false) ): [Instance!] @hasMany @scope(name: "active", parameters: [$includeExpired]) }
对应的作用域调整为:
public function scopeActive($query, bool $includeExpired = false) { if (!$includeExpired) { return $query->where('start_date', '>=', now()); } return $query; }
方案二:使用模型方法 + @method 指令(即你猜测的实现方式)
如果你希望通过自定义方法完全控制返回逻辑,可按以下步骤实现:
- 在Course模型中添加获取有效场次的方法,自行处理参数逻辑:
// app/Models/Course.php public function activeInstances(array $orderBy = []) { $query = $this->instances()->where('start_date', '>=', now()); // 手动处理排序逻辑 foreach ($orderBy as $item) { $query->orderBy($item['field'], $item['order']); } return $query->get(); }
- 修改Schema定义,将原有的
@hasMany替换为@method指令:
type Course{ id: ID! title: String! instances( "Order by date" orderBy: [OrderByClause!] ): [Instance!] @method(name: "activeInstances") }
内容的提问来源于stack exchange,提问作者ElendilTheTall
相关产品推荐
相关产品推荐

