1
votes

I'm learning laravel, but i've ran into a problem and i can't seem to get it right. I have two models :

Model 'Group' :

 Schema::create('groups', function (Blueprint $table) {
        $table->increments('id')->unique();
        $table->string('name')->unique();
        $table->text('description')->nullable();
        $table->string('picture')->nullable();
        $table->timestamps();
    });

and model 'User' :

Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('first_name');
        $table->string('last_name');
        $table->string('email')->unique();
        $table->string('password');
        $table->timestamp('email_verified_at')->nullable();
        $table->timestamps();
        $table->rememberToken();
    });

These models should have a many-to-many relationship, so i've created a pivot table named 'group_user' :

Schema::create('group_user', function (Blueprint $table) {
        $table->increments('id');

        $table->integer('group_id')->unsigned();
        $table->foreign('group_id')->references('id')->on('groups')->onDelete('cascade');

        $table->integer('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

        $table->timestamps();
    });

Next i defined the many-to-many relationship :

In the 'Group' model :

 public function members()
{
    return $this->belongsToMany('App\User', 'group_user', 'group_id', 'user_id')->withTimestamps();
}

In the 'User' model :

public function groups() {
    return $this->belongsToMany('App\Group', 'group_user', 'user_id', 'group_id')->withTimestamps();
}

In my database i have a pivot record, that links group 1 to user 1 :

+----+----------+---------+------------+------------+
| id | group_id | user_id | created_at | updated_at |
+----+----------+---------+------------+------------+
|  1 |        1 |       1 | NULL       | NULL       |
+----+----------+---------+------------+------------+

So far so good, but when i try to print the members of group 1 :

@foreach($group->members() as $user)
   <p>{{ $user->first_name }}</p>
@endforeach

i get this error :

Trying to get property 'first_name' of non-object

When i print the user object like this

 @foreach($group->members() as $user)
   <p>{{ $user }}</p>
@endforeach

I get the result 1, which is the user_id of the member. Can anyone point out where i messed up? Been looking at it for hours, but i just can't see it. Thanks in advance!

1
try $group->members instead of $group->members(). You are calling the relationship query, not the relationship Collection result - Christophe Hubert
Oh dear lord, that's it. I've been looking at this for so long that i've started doubting every line, thank you so much! Just to make sure i understand this, why does members() return an id? "members()" is a public function, so why can't it be called with brackets? - TimCreemers
It should return a belongsToMany relationship instance, so I guess the integer you see is some kind of casting when you display the result from within the Blade brackets. Also, on a side note, be sure to get familiar with the concepts of eager loading and what the difference between $group->members and $group->members()->get() is. :) - D. Petrov
$group->members() doesn't return an ID (it looks like an ID, but that's a false positive), it returns a Builder instance. And running foreach({Builder} as $user) returns false (or true I guess?), and false doesn't have an attribute ->first_name (hence the error). $group->members (without the ()) is a Collection, which is compatible with a foreach(). - Tim Lewis
Thanks everyone, it all makes sense now. - TimCreemers

1 Answers

2
votes

try $group->members instead of $group->members(). Because $group->members() return the relationship builder.