Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Laravel Many To Many Get element that I dont have a relationship with

In laravel Many to Many relationship like the one in the Laravel Documentation example.
https://laravel.com/docs/9.x/eloquent-relationships#many-to-many

users
    id - integer
    name - string

roles
    id - integer
    name - string

role_user
    user_id - integer
    role_id - integer

In the Users model I have

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

In the Roles model I have

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

How can I get all Role that I don’t have a relationship to.

I tried thing like

$this->availableRoles = Role::doesntHave('users')->get();

But this give me all the Role that no user at all have

Any hint on this.

>Solution :

If you already have a User instance (I assume that is what $this is?), then you can simply filter the relationship:

$this->availableRoles = Role::whereDoesntHave('users', function ($subQuery) {
  return $subQuery->where('users.id', $this->id);
})->get();

This should return all Role elements, unless that Role has an association with the User ($this, $user, auth()->user(), etc.; adjust as required).

An alternative approach, filter out Role based on existing Roles:

$this->availableRoles = Role::whereNotIn('id', $this->roles->pluck('id'))->get();

This approach get’s the roles.id for the User instance.

You can take a look at query efficiency and use the one that works best, but either approach should work fine.

Note: If $this is not a User instance, adjust:

$user = User::find($userId); // or `auth()->user()`, etc.

$availableRoles = Role::whereDoesntHave('users', function ($subQuery) use ($user) {
  return $subQuery->where('users.id', $user->id);
})->get();

// OR

$availableRoles = Role::whereNotIn('id', $user->roles->pluck('id'))->get();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading