You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:18:42