定制 abdelhamiderrahmouni/laravel-pivot-relations-eager-loading 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

abdelhamiderrahmouni/laravel-pivot-relations-eager-loading

最新稳定版本:v1.0.0

Composer 安装命令:

composer require abdelhamiderrahmouni/laravel-pivot-relations-eager-loading

包简介

A Laravel package that enables eager loading of relationships on pivot tables for BelongsToMany and MorphToMany relationships.

README 文档

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

A Laravel package that enables eager loading of relationships on pivot tables for BelongsToMany and MorphToMany relationships.

Problem

Laravel doesn't natively support eager loading relationships defined on custom pivot models. When you try to eager load pivot relationships using with('roles.pivot.assignedBy'), you get:

Illuminate\Database\Eloquent\RelationNotFoundException: Call to undefined relationship [pivot] on model [App\Models\Role].

Solution

This package provides custom relationship classes that extend Laravel's BelongsToMany and MorphToMany relationships, adding support for eager loading pivot relationships natively using ->with('roles.pivot.createdBy') as well as via a withPivotRelations('createdBy') method.

This package supports the get(), lazy(), cursor(), and chunk() methods.

Installation

composer require abdelhamiderrahmouni/laravel-pivot-relations-eager-loading

Usage

1. Create a Custom Pivot Model

Make sure to define your relationships on your custom pivot model:

<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Pivot;

class UserSkill extends Pivot
{
    protected $table = 'user_skill';

    public function scale(): BelongsTo
    {
        return $this->belongsTo(Scale::class);
    }
}

2. Add the Trait to Your Models

<?php

declare(strict_types=1);

namespace App\Models;

use LaravelPivotRelationsEagerLoading\Concerns\WithPivotRelationsLoading;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use WithPivotRelationsLoading;

    public function skills(): BelongsToMany
    {
        return $this->belongsToMany(Skill::class, 'user_skill')
            ->using(UserSkill::class)
            ->withTimestamps()
            ->withPivot(['scale_id']);
    }
}
$users = User::query()->with('skills.pivot.scale')->get();

foreach ($users as $user) {
    foreach ($user->skills as $skill) {
        // The scale relationship is already loaded - no N+1 queries!
        $scale = $skill->pivot->scale;
    }
}

If you prefer to always eager load a pivot relationship with your relationship definition, you can use the withPivotRelations() method:

<?php

declare(strict_types=1);

namespace App\Models;

use LaravelPivotRelationsEagerLoading\Concerns\WithPivotRelationsLoading;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use WithPivotRelationsLoading;

    public function skills(): BelongsToMany
    {
        return $this->belongsToMany(Skill::class, 'user_skill')
            ->using(UserSkill::class)
            ->withTimestamps()
            ->withPivot(['scale_id'])
            ->withPivotRelations('scale');
    }
}

3. Query with Eager Loading

$users = User::query()->with('skills')->get();

foreach ($users as $user) {
    foreach ($user->skills as $skill) {
        // The scale relationship is already loaded - no N+1 queries!
        $scale = $skill->pivot->scale;
    }
}

Polymorphic Relationships

The package also supports MorphToMany relationships:

<?php

declare(strict_types=1);

namespace App\Models;

use LaravelPivotRelationsEagerLoading\Concerns\WithPivotRelationsLoading;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use WithPivotRelationsLoading;

    public function tags(): MorphToMany
    {
        return $this->morphToMany(Tag::class, 'taggable')
            ->using(Taggable::class)
            ->withPivotRelations('creator');
    }
}

For inverse polymorphic relationships, use morphedByMany():

public function posts(): MorphToMany
{
    return $this->morphedByMany(Post::class, 'taggable')
        ->using(Taggable::class)
        ->withPivot('added_by')
        ->withPivotRelations('addedBy');
}

Notes:

  • The package automatically detects and strips pivot.* (or alias.*) from the relation eager-loads and loads those relations on the pivot models. This avoids RelationNotFoundException on the related model.
  • You can use withPivotRelations([...]) if you prefer an explicit API; both forms are supported and can be combined.

Available Classes

This package provides two classes that simply extend Laravel's native relations:

  • LaravelPivotRelationsEagerLoading\Relations\BelongsToMany (extends Illuminate\Database\Eloquent\Relations\BelongsToMany)
  • LaravelPivotRelationsEagerLoading\Relations\MorphToMany (extends Illuminate\Database\Eloquent\Relations\MorphToMany)

Using them is optional; the trait works fine with the native Illuminate types shown in the examples above.

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Credits

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 2
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-12-22