2

I am trying to retrieve all related models with another model through an intermediary table but can't figure out how. The Laravel docs say you can do something like this:

$roles = App\User::find(1)->roles()->orderBy('name')->get();

But when I try to apply that to my code

$roles = User::where('id', $user->id)->roles()->get();

It does not work. I am accepting the user model through my controller, so I do have access to it.

The relationship is also defined like so:

User

public function roles()
{
    return $this->belongsToMany(Role::class);
}

Role

public function users()
{
    return $this->belongsToMany(User::class);
}

How can I get all of the roles associated with a particular user?

edit/update: I know I can simply use a foreach loop and get all of the roles associated with a particular user, but I am trying to return a resource collection, so I cannot do it that way

develpr
  • 1,296
  • 4
  • 22
  • 42

5 Answers5

1

the problem with your second approach is calling roles() function on an 'Eloquent Query Builder' instance. You need to make sure to call roles() function on a 'User Model'.

this part of code User::where('id', $user->id) doesn't return a 'User Model'.

To get an 'User Model' from a 'Query Builder' instance you need to call first() function.

possible solution.

$roles = User::where('id', $user->id)->first()->roles;
Tharaka Dilshan
  • 4,371
  • 3
  • 14
  • 28
  • This answer has the most details needed. And anyway, _`User::where('id', $user->id)->first()`_ can just be simplified to _`User::find($id)`_ – Dexter Bengil Sep 27 '18 at 18:17
1

Try this, I am assuming that $user_id is the parameter which is passed into the controller from the URL,

$roles=User::findOrFail($user_id)->roles;

But before running the above code, I assume that you have created the pivot table for many to many relationship with columns user_id and role_id. And have named the pivot table as role_user.

Hope this works

Jason Guru
  • 264
  • 5
  • 10
1

The reason why you're getting the errors, is because before calling the method first() (or find() or findOrFail()), the instance is a QueryBuilder. and the roles() method exist only on an User::class instance.

if you are trying to get the user with an attribute roles containing a collection (array) of all his roles do:

$user = User::where('id', $user->id)->with('roles')->first();

if you need just the array of roles, you have two choices; either get the user and then get his roles:

$user = App\User::find($userId);
$roles = $user->roles()->orderBy('name')->get();
//the same as
$roles = App\User::find($userId)->roles()->orderBy('name')->get();

or get the Roles (only one query)

$roles = Role::whereHas('users', function($users) use($userId) {
    $users->where('id','=',$userId);
})->get();

Hope this gives you enough insight to build the exact code you need.

N69S
  • 16,110
  • 3
  • 22
  • 36
0

You can use the following solution to retrieve all related models in a many to many relationship in Laravel:

$roles = User::where('id', $user->id)->get();
 foreach($roles as $rol){
  $rol->roles;
 }
Grant Miller
  • 27,532
  • 16
  • 147
  • 165
0

User

use App\User;
public function roles()
{
   return $this->belongsToMany('App\Users', 'user_id');
}

Role

use App\Roles;
public function users()
{
    return $this->belongsToMany('App\Roles');
}

Controller

$roles = User::where('id', $user->id)->roles()->get();

Try this one. I think your relationship is not correct.

You can read more information here Many To Many

Christian Gallarmin
  • 660
  • 4
  • 15
  • 34