1
votes
Edit:
I dont think its the same issue as:
https://stackguides.com/questions/40022929/laravel-relationship-error-undefined-property-illuminate-database-eloquent-col
because in that issue hasMany relationship is used which returns an array but i used belongsTo which should return a certain object.

I have a database structure where i have a many to many relationship between users and companies table. For that i have a crossreference table company_user. Also each user has a certain role in a company so the crossreference table also has a role_id. The problem is that for some reason i get an exception when i try retrieve the role from the crossreference table.

Here is how i defined the relationship in Company model:

public function users() {
    return $this->belongsToMany('App\User')->withPivot('role_id')->using('App\CompanyUser');
}

Now if i just try to get role_id from pivot everything works fine:

@foreach($company->users as $user)
    {{$user->pivot->role_id}} // this displays correct role_id
@endforeach

But i also need the data of the role so i defined a relationship in my custom pivot. Here is the whole model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Relations\Pivot;

class CompanyUser extends Pivot
{
    public function role()
    {
        return $this->belongsTo('App\Role');
    }
}

And i tried to access it like this:

@foreach($company->users as $user)
    {{$user->pivot->role()->id}}
@endforeach

But this gives me an exception:

Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$id 

What am I missing?

2

2 Answers

6
votes

try changing to

@foreach($company->users as $user)
    {{$user->pivot->role->id}}
@endforeach
1
votes

The exception itself gives you your answer.

Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$id 

It's telling you you're trying to access the $id property on the belongs to builder instance and not the actual related model.

The difference is small but is worth understanding as it will make your laravel life much happier.


Access the relation builder: $user->role()

This will directly call the role() method and return exactly what you see in your definition. Accessing this method is handy for aggregate functions - things like getting the count of related records for HasMany or BelongsToMany relations. eg: $user->role()->count().


Access the related record: $user->role

This will actually retrieve the related record from the database and hydrate it for you, thus giving you the power of your related eloquent model and access to it's columns as properties. :D

You can see why/how this works by diving into Laravel's source and checking out the Illuminate\Database\Eloquent\Model class. Specifically the getAttribute() method.