Eager Loading: Use `with` on pivot with eloquent relationship
The current accepted answer deviates from the original data structure. I created a package which can help you achieve what you want and also it maintains the original data structure. Please read my medium story here: https://medium.com/@ajcastro29/laravel-eloquent-eager-load-pivot-relations-dba579f3fd3a
First, create your custom pivot model and define relations on pivot model, in your case:
use Illuminate\Database\Eloquent\Relations\Pivot;
class BundleProduct extends Pivot
{
public function price()
{
return $this->belongsTo(Price::class);
}
}
Then use the pivot model in the relation:
class Bundle extends Model
{
public function products()
{
return $this->belongsToMany(Product::class)
->withPivot('price_id') // this is needed to query the relation `price`
->using(BundleProduct::class);
}
}
Make sure you use the trait AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait
in the Product
model because it is the related model in belongsToMany relation. This let us enable eager loading the pivot relations.
use AjCastro\EagerLoadPivotRelations\EagerLoadPivotTrait;
class Product extends Model
{
use EagerLoadPivotTrait;
}
Then eager load it like this:
$bundle = Bundle::with('products.pivot.price')->first();
$price = $bundle->products->first()->pivot->price;
One solution could be adding a BundleProduct
model for the pivot. Then link the BundleProduct object to Bundle model:
class Bundle extends Model
{
public function bundleProducts()
{
return $this->hasMany(BundleProduct::class, 'bundle_id', 'id');
}
}
To get all your bundles with their associated products and prices in this bundle, just do:
Bundle::with('bundleProducts.product', 'bundleProducts.price')->get();
That worked for me, hope it could help someone else.