Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ficus's avatar
Level 1

Pivot tables, scope eager loading

Hi there!

I have three tables:

  • users
  • products
  • tokens

Token structure is: id, user_id, product_id, amount, timestamps Basically, this model represent which products and how many of them user can obtain. For example - if user has token for product with id 1 and amount 20 - he can obtain 20 products with id 1. Simple as that.

It's been a long time and my head is wasted. I feel that I am missing a point there.

Each table has relatable model: User:

public function tokens()  
{  
  return $this->hasMany(Token::class);  
}

Product

public function tokens()  
{  
  return $this->hasMany(Token::class);  
}

Token

public function user()  
{  
  return $this->belongsTo(User::class);  
}  
  
public function product()  
{  
  return $this->belongsTo(Product::class);  
}  
  
public function scopeOwnedBy($query, $user_id = null)  
{  
  return $query->where('user_id', $user_id ?? Auth()->id())->first();  
}

Did I do my relationships correctly?

Right now I want to be able:

  • display for a logged user a list of ALL products with eager loaded amount of tokens (owned by this user) for each of them
  • display amount of all tokens for a given product globally (in admin panel)

Quite ugly but kind of working was eager load product with tokens and then use scope ownedBy()->amount on that. However, it only works in function dd() - if I try to print it with blade I receive error: "Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$amount (View:"

What am I doing wrong that I can't obtain it?

0 likes
1 reply
staudenmeir's avatar

This is a case for a BelongsToMany relationship (documentation):

class User extends Model
{
    public function products()
    {
        return $this->belongsToMany(Product::class, 'tokens')->withPivot('amount');
    }
}

Please or to participate in this conversation.