Laravel 8多态关联场景下给关联模型应用where条件的问题咨询
问题解决方法
1. 原因说明
morphWith仅用于预加载多态关联对应模型的嵌套关联,本身不支持条件过滤,直接在外层使用whereHas无法穿透到多态关联绑定的Events、Meeting模型的assignee子关联,所以条件不生效。
2. 临时查询添加条件
Laravel专为多态关联提供了whereHasMorph方法用于条件查询,示例代码如下:
// 示例:查询assignee id为1的MainEvent记录 $mainEvents = MainEvent::whereHasMorph( 'eventheadable', [Events::class, Meeting::class], function ($query) { $query->whereHas('assignee', function ($assigneeQuery) { // 此处写入你需要的assignee查询条件 $assigneeQuery->where('id', 1); }); } )->get();
如果需要同时预加载符合条件的assignee数据,结合with使用即可:
$mainEvents = MainEvent::whereHasMorph( 'eventheadable', [Events::class, Meeting::class], fn($q) => $q->whereHas('assignee', fn($aq) => $aq->where('id', 1)) )->with(['eventheadable.assignee' => fn($aq) => $aq->where('id', 1)])->get();
3. 关联定义固定条件
如果需要所有调用eventheadable关联的场景都自动添加assignee过滤条件,直接修改关联定义即可:
class MainEvent extends Model { public function eventheadable() { // 条件一致的话可以把闭包提出来复用,减少重复代码 $assigneeFilter = function ($query) { $query->where('status', 1); // 替换为实际需要的条件 }; return $this->morphTo('eventhead', 'event_type_id', 'event_id') ->morphWith([ Events::class => ['assignee' => $assigneeFilter], Meeting::class => ['assignee' => $assigneeFilter], ]); } }
4. 注意事项
- 确认
Events和Meeting模型内的多对多关联名和代码中使用的assignee一致,若实际为复数assignees需要同步修改,避免关联加载失败 - 确保两个模型的
assignee关联定义正确,多对多关联的中间表、外键配置无误
内容的提问来源于stack exchange,提问作者Jayesh Kannan
相关产品推荐
相关产品推荐

