Need help with eager-load-pivot-relations?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

ajcastro
130 Stars 7 Forks 8 Commits 2 Opened issues

Description

Eager load pivot relations for Laravel Eloquent's BelongsToMany relation.

Services available

!
?

Need anything else?

Contributors list

# 5,933
PHP
axios
vuejs
Laravel
1 commit
# 461,328
PHP
Laravel
locale
portugu...
1 commit

Laravel Eloquent: Eager Load Pivot Relations

Eager load pivot relations for Laravel Eloquent's BelongsToMany relation.
Medium Story: https://medium.com/@ajcastro29/laravel-eloquent-eager-load-pivot-relations-dba579f3fd3a

Installation

composer require ajcastro/eager-load-pivot-relations

Usage and Example

There are use-cases where in a pivot model has relations to be eager loaded. Example, in a procurement system, we have the following:

Tables

items
 - id
 - name

units

  • id
  • name (pc, box, etc...)

plans (annual procurement plan)

  • id

plan_item (pivot for plans and items)

  • id
  • plan_id
  • item_id
  • unit_id

Models

class Unit extends \Eloquent {
}



use AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait; class Item extends \Eloquent { // Use the trait here to override eloquent builder. // It is used in this model because it is the relation model defined in // Plan::items() relation. use EagerLoadPivotTrait;

public function plans()
{
    return $this->belongsToMany('Plan', 'plan_item');
}

}

class Plan extends \Eloquent { public function items() { return $this->belongsToMany('Item', 'plan_item') ->using('PlanItem') // make sure to include the necessary foreign key in this case the unit_id ->withPivot('unit_id', 'qty', 'price'); } }

// Pivot model class PlanItem extends \Illuminate\Database\Eloquent\Relations\Pivot { protected $table = 'plan_item';

public function unit()
{
    return $this->belongsTo('Unit');
}

}

From the code above,

plans
and
items
has
Many-to-Many
relationship. Each item in a plan has a selected
unit
, unit of measurement. It also possible for other scenario that the pivot model will have other many relations.

Eager Loading Pivot Relations

Use keyword

pivot
in eager loading pivot models. So from the example above, the pivot model
PlanItem
can eager load the
unit
relation by doing this:
return Plan::with('items.pivot.unit')->get();

The resulting data structure will be:

image

You may also access other relations for example:

return Plan::with([
  'items.pivot.unit',
  'items.pivot.unit.someRelation',
  'items.pivot.anotherRelation',
  // It is also possible to eager load nested pivot models
  'items.pivot.unit.someBelongsToManyRelation.pivot.anotherRelationFromAnotherPivot',
])->get();

Custom Pivot Accessor

You can customize the "pivot accessor", so instead of using the keyword

pivot
, we can declare it as
planItem
. Just chain the
as()
method in the definition of the
BelongsToMany
relation.
class Plan extends \Eloquent
{
    public function items()
    {
        return $this->belongsToMany('Item', 'plan_item')
            ->withPivot('unit_id', 'qty', 'price')
            ->using('PlanItem')
            ->as('planItem');
    }
}

Make sure we also use the trait to our main model which is the

Plan
model, because the package needs to acess the belongsToMany relation (
items
relation) to recognize the used pivot acessor.
use AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait;

class Plan extends \Eloquent { use EagerLoadPivotTrait; }

So instead of using

pivot
, we can eager load it by defined pivot accessor
planItem
.
return Plan::with('items.planItem.unit')->get();
$plan = Plan::with('items.planItem.unit');

foreach ($plan->items as $item) { $unit = $item->planItem->unit; echo $unit->name; }

Other Examples and Use-cases

https://github.com/ajcastro/eager-load-pivot-relations-examples

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.