Laravel 11:如何通过带中间表的模型实现Has Many Through关联?
Laravel 11 多层级关联关系配置问题
现有模型关联说明
A模型:自定义主键为
pidprotected $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
相关产品推荐
相关产品推荐

