Laravel使用hasManyThrough关联多态morphMany获取文件数据异常
问题原因
原生Laravel的hasManyThrough方法本身不直接支持多态关联场景,它只会按外键ID匹配关联,不会自动带上多态要求的*_type类型约束字段。你之前的定义只匹配了filable_id和文档ID的对应关系,没有限定filable_type必须是Document模型类,会把Medical、Course等其他关联模型同ID的文件也纳入匹配范围,最终导致关联查询逻辑错位,触发模型找不到的错误。
另外你代码里有一处拼写错误需要先修复:File模型的$fillable属性中写的是fiable_id,和迁移生成的实际字段filable_id不符(少了字母l),如果用批量赋值写入文件数据,会导致多态关联ID字段没有正确存值,也会造成查询无结果。
正确定义方式
在原有hasManyThrough定义的基础上,追加多态类型的查询约束即可,以Document关联的文件为例:
// Worker模型内 public function document_files() { return $this->hasManyThrough( File::class, Document::class, 'worker_id', // Document表关联Worker的外键字段 'filable_id', // File表关联中间模型的多态ID字段 'id', // Worker表主键 'id' // Document表主键 )->where('files.filable_type', Document::class); // 关键:限定多态关联的模型类型 }
Medical、Course对应的文件关联定义逻辑完全一致,只需要替换中间模型和对应的类型约束即可:
public function medical_files() { return $this->hasManyThrough( File::class, Medical::class, 'worker_id', 'filable_id', 'id', 'id' )->where('files.filable_type', Medical::class); } public function course_files() { return $this->hasManyThrough( File::class, Course::class, 'worker_id', 'filable_id', 'id', 'id' )->where('files.filable_type', Course::class); }
扩展:获取Worker下所有关联文件
如果需要一次性拿到Worker下三类关联的所有文件,可以在Worker模型中定义一个访问器合并三个关联的结果:
public function getAllFilesAttribute() { return $this->document_files ->merge($this->medical_files) ->merge($this->course_files); }
调用时直接通过$worker->all_files即可获取全部关联文件。
内容的提问来源于stack exchange,提问作者nabina khadka
相关产品推荐
相关产品推荐

