Laravel Query Scope查询时如何携带关联Pivot表信息
解决Laravel多对多关联中获取中间表额外字段的问题
看起来你已经搞定了筛选Workout的Query Scope,但想顺便把中间表的date、program、warmup字段也拿回来对吧?这里分两种常用场景给你解决方案:
场景1:通过关联预加载(with)获取pivot字段
首先得确保Workout模型里的weeks多对多关联,明确指定要携带的中间表额外字段。打开Workout模型修改关联方法:
// 在Workout模型中 public function weeks() { // 替换Week::class为你的实际关联模型类名,如果中间表不是默认命名,记得加第三个参数指定表名 return $this->belongsToMany(Week::class) ->withPivot('date', 'program', 'warmup'); // 这里添加你需要的中间表字段 }
现在再调用Workout::programdate('skunks', Carbon::today())->with('weeks')->first(),返回的Workout实例里,每个关联的Week模型的pivot属性就会包含这三个字段了。访问方式示例:
$workout = Workout::programdate('skunks', Carbon::today())->with('weeks')->first(); // 假设只关联了一个符合条件的Week echo $workout->weeks->first()->pivot->date; echo $workout->weeks->first()->pivot->program;
场景2:直接把中间表字段作为Workout的属性返回
如果你的Query Scope是筛选单个符合中间表条件的Workout,而且只需要对应那条中间表记录的字段,用关联预加载就有点多余(会加载所有关联的weeks),这时可以用join直接查询并把中间表字段选出来:
方法:修改Query Scope,加入join和字段选择
// 在Workout模型的Scope方法中 public function scopeProgramdate($query, $program, $date) { return $query->select('workouts.*', 'workout_week.date', 'workout_week.program', 'workout_week.warmup') ->join('workout_week', 'workouts.id', '=', 'workout_week.workout_id') // 替换成你的实际中间表名 ->where('workout_week.program', $program) ->whereDate('workout_week.date', $date); }
调用时直接访问字段就行,不用走pivot:
$workout = Workout::programdate('skunks', Carbon::today())->first(); echo $workout->date; echo $workout->program;
小提醒
- 中间表名默认是两个模型名按字母顺序拼接(比如Workout和Week对应
workout_week),如果你的表名不一样,记得在belongsToMany或join里写正确的名称。 - 用
whereDate时,确保date字段是日期类型,或者Carbon能正确解析的格式。
内容的提问来源于stack exchange,提问作者Packy
相关产品推荐
相关产品推荐

