Laravel三级一对多关联查询:获取指定季的所有剧集
从Series关联到指定季的所有剧集解决方案
嘿,我来帮你搞定这个Laravel关联的问题!要实现从Series模型关联到指定季的所有剧集,咱们先把模型关联配置好,再看具体的查询方式:
第一步:配置模型的关联关系
首先确保三个模型的关联关系正确对应你的数据表结构:
Series 模型(app/Models/Series.php)
一个剧集(Series)对应多个季,所以用hasMany关联到Seasons模型:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class Series extends Model { // 如果你的表名不是默认的series,这里指定 protected $table = 'series'; /** * 关联到该剧集的所有季 */ public function seasons(): HasMany { // 第二个参数是series_seasons表中关联series的外键,按需调整 return $this->hasMany(Seasons::class, 'series_id'); } }
Seasons 模型(app/Models/Seasons.php)
一个季对应多个剧集,同时反向关联到Series:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Seasons extends Model { // 指定对应的数据表名 protected $table = 'series_seasons'; /** * 关联到该季的所有剧集 */ public function episodes(): HasMany { // 第二个参数是series_espisodes表中关联series_seasons的外键,按需调整 return $this->hasMany(Episodes::class, 'season_id'); } /** * 反向关联到所属的剧集 */ public function series(): BelongsTo { return $this->belongsTo(Series::class, 'series_id'); } }
Episodes 模型(app/Models/Episodes.php)
反向关联到所属的季:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; class Episodes extends Model { // 指定对应的数据表名 protected $table = 'series_espisodes'; /** * 关联到所属的季 */ public function season(): BelongsTo { return $this->belongsTo(Seasons::class, 'season_id'); } }
第二步:获取指定Series的指定季剧集
有几种灵活的方式可以实现需求,根据你的场景选择:
方式1:链式关联查询(直观易懂)
先找到目标Series,再定位到指定季,最后获取剧集:
// 示例:获取ID为1的Series的第2季所有剧集 $series = Series::find(1); // 假设你的series_seasons表有`number`字段存储季数(比如1、2、3...) $targetSeason = $series->seasons()->where('number', 2)->first(); // 获取该季的所有剧集(使用?避免空对象报错) $episodes = $targetSeason?->episodes;
也可以简化成一行链式调用:
$episodes = Series::find(1)->seasons()->where('number', 2)->first()?->episodes;
方式2:直接通过Episodes模型查询(更高效)
如果不需要Series或Season的其他数据,直接从Episodes模型出发,通过关联条件筛选:
$episodes = Episodes::whereHas('season', function ($query) { $query->where('series_id', 1) // 指定目标Series的ID ->where('number', 2); // 指定目标季数 })->get();
方式3:在Series模型中添加便捷方法(复用性高)
如果经常需要这个查询逻辑,可以在Series模型里封装一个方法:
// 在Series模型中添加 public function getSeasonEpisodes(int $seasonNumber) { return $this->seasons() ->where('number', $seasonNumber) ->with('episodes') // 预加载避免N+1查询 ->first()?->episodes; } // 使用时直接调用: $series = Series::find(1); $episodes = $series->getSeasonEpisodes(2);
优化小提示
- 避免N+1查询问题:如果需要同时获取多个Series的季和剧集,记得用
with预加载关联:$seriesList = Series::with('seasons.episodes')->get(); - 字段名检查:确保所有外键字段(比如
series_id、season_id)和你的数据库表结构一致,这是关联出错的常见原因。
内容的提问来源于stack exchange,提问作者crowley
相关产品推荐
相关产品推荐

