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

Laravel 11:如何通过带中间表的模型实现Has Many Through关联?

Laravel 11 多层级关联关系配置问题

现有模型关联说明

  • A模型:自定义主键为pid

    protected $primaryKey = 'pid';
    

    与L模型的一对多关联:

    public function speaker(): HasMany
    {
        return $this->hasMany(L::class, 'speaker_id', 'pid');
    }
    
  • T模型:与A模型通过中间表account_tag建立多对多关联

    public function accounts(): BelongsToMany
    {
        return $this->belongsToMany(A::class, 'account_tag', 'tag_id', 'account_id', 'id', 'pid');
    }
    

需求目标

在T模型中建立关联,直接获取所有通过account_tag关联的A模型对应的L模型数据(即L中的speaker_ids)。

无效尝试

使用hasManyThrough但未生效:

public function likes()
{
    return $this->hasManyThrough('App\Models\L', 'App\Models\A', 'tag_id', 'pid', 'tags.id', 'accounts.pid');
}

解决方案

方案1:修正hasManyThrough参数并补充中间表关联

由于T与A是多对多关系,需要手动加入中间表的关联条件,正确配置如下:

use Illuminate\Database\Eloquent\Relations\HasManyThrough;

public function likes(): HasManyThrough
{
    return $this->hasManyThrough(
        L::class,
        A::class,
        'pid',          // A模型关联L的对应字段
        'speaker_id',   // L模型关联A的外键
        'id',           // T模型的主键
        'pid'           // A模型的主键
    )->join('account_tag', 'account_tag.account_id', '=', 'a.pid')
      ->where('account_tag.tag_id', '=', $this->id)
      ->select('l.*')
      ->distinct();
}

方案2:利用已有嵌套关联实现

通过T模型已有的accounts关联,间接查询L模型数据:

public function likes()
{
    return L::whereIn('speaker_id', $this->accounts()->pluck('pid'));
}

关键注意点

  • hasManyThrough默认适配一对多→一对多的层级关联,T与A是多对多关系,因此必须手动补充中间表的关联过滤条件。
  • 需严格对应各模型的主键、外键:A的主键为pid,L关联A的外键是speaker_id,T的主键为id,中间表account_tag通过tag_id关联T、account_id关联A。

内容的提问来源于stack exchange,提问作者devloper2024ornot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:01:04