I have a model Product
, and the same product can be sold by multiple supermarkets and outlets, so I define two BelongsToMany
relationships for them:
class Product extends Model
{
public function supermarkets(): BelongsToMany
{
return $this->belongsToMany(
Supermarket::class,
'product_supermarket',
'product_id',
'supermarket_id'
);
}
public function outlets(): BelongsToMany
{
return $this->belongsToMany(
Outlet::class,
'outlet_product',
'product_id',
'outlet_id'
);
}
}
Then in the Supermarket
model I define a BelongsToMany
relastionship to Products
model, since one supermarket can sell many different products.
class Supermarket extends Model
{
public function products(): BelongsToMany
{
return $this->belongsToMany(
Product::class,
'product_supermarket',
'supermarket_id',
'product_id'
);
}
}
If I want to access the intermediate table product_supermarket
, I can:
foreach ($supermarket->products as $product) {
echo $product->pivot->created_at;
}
However, we see that Product
model has two BelongsToMany
defined in its class. So what will property pivot
be like in such a case? How can I access the intermediate table product_supermarket
or outlet_product
specifically?
I read the official documentation of Laravel but found nothing about it metioned in it: https://laravel.com/docs/11.x/eloquent-relationships
2
Answers
I've figured it out. So if you want to return a specific intermediate table by 'pivot', you need to get the related model instances from the model that this intermediate table is bounded to. For example:
You can use https://laravel.com/docs/11.x/eloquent-relationships#customizing-the-pivot-attribute-name to alias the pivot attribute name for each relationship you have.
and the reverse if you need it.
Then you can access each one by it’s pivot alias
outlets_pivot
orsupermarkets_pivot
I also recommend to eager load those relationships since you are already looping through all of them to avoid n+1 query if you are querying multiple supermarkets.Also note that
the pivot here will always be the pivot related to the product and supermarket.
and here it will always be for the outlets and products.
So you might not need the alias in most cases.