mark
mark

Reputation: 121

Laravel many to many relations say no method users

I have two models which are User and Group and they have a many-to-many relationship.

Group.php

<?php

namespace BOOK_DONATION;

use Illuminate\Database\Eloquent\Model;

class group extends Model
{
    protected $fillable = [
        'id','book_id',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [

    ];
    public function users(){
        return $this->belongsToMany('BOOK_DONATION\User', 'group_user')->withPivot('last_seen_id');
    }
}

User.php

amespace BOOK_DONATION;
use Illuminate\Http\Request;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use BOOK_DONATION\User;
use BOOK_DONATIOM\Book;
use BOOK_DONATION\group;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email','country','state/provience','city', 'token', 'password','postal_code',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password','verfied', 'remember_token',
    ];

    public function Book(){
        return $this->hasMany('App\Book');
    }

    public function groups(){
        return $this->belongsToMany('BOOK_DONATION\group', 'group_user')->withPivot('last_seen_id');
    }

}

Now I have controller with the following line:

return view('chat.messaging')->with('group',$group->users());

What I get is:

Method Illuminate\Database\Eloquent\Collection::users does not exist.

But as you can see, the Group model does have a users method, so what is the problem?

Upvotes: 0

Views: 491

Answers (2)

Jason
Jason

Reputation: 3030

It's telling you that $group is a Collection of group models, not a single instance of a Group model. The Collection itself does not have a method called users.

In your controller, how is $group defined? If you're doing a query such as group::all(), you'll end up with a Collection.

Calling:

Group::with(['users'])->all();

will load all the groups AND all the users. and then you can iterate through each group and have all the users.

Edit:

As per Mark's comment on his query, he should be changing his get to a first to get a single model as a result.

$group = group::with(['users'])->where('id', '=', $group_id)->first();

and the remove the parentheses on the call to the view

return view('chat.messaging')->with('group',$group->users);

Upvotes: 3

Kenny Horna
Kenny Horna

Reputation: 14241

At the moment I see an error:

When you call a relation with the parentheses () at the end, you will access the relationship itself, this means that you can keep adding query contraints, for example:

// with the following you access all the users of the relationship.
$group->users()->get();
// with the following you access all the users of the relationship with an id=123
$group->users()->where('user_id', 123)->get();

Now, when you do it without the parentheses () at the end, you access the result of the relationship, this means, the elements that exist in that relation.

So, in this case, the users of that specific $group. This will be an instance of Collection, a collection of User models, that is what you should return to the view in your case:

return view('chat.messaging')->with('group', $group->users);
// or
return view('chat.messaging')->withGroup($group->users);

Now, if we look at your error message:

Method Illuminate\Database\Eloquent\Collection::users does not exist.

This is telling you that $group doesn't have a users method but as we can see in your code it does have one. The problem must be how you are getting the $group object, probably you are doing one the following:

$group = App\Group::where('id', 'some_id')->get();
// or
$group = App\Group::all();

This will also return a collection of items (get() / all()), do this instead:

$group = App\Group::where('id', 'some_id')->first();

or even better:

$group = App\Group::find('some_id');

Those will return an instance of a Group model, a single object instead of a collection, that must has the users method defined in it.

Upvotes: 0

Related Questions