Search code examples
phpmysqllaraveleloquenthas-and-belongs-to-many

Laravel Eloquent exclude specific result from belongsToMany() query


On the User.php model I have the following relationship:

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

In the database, I have different roles and basically I want to return all the roles, except the "superadmin" role so that it cannot be displayed in the views or wherever I will choose to show the roles.

I've tried something like:

public function roles()
{
    return $this->belongsToMany(Role::class)->where('name', '!=', 'superadmin');
}

... but it doesn't work. I assume it has something to do with the pivot table. I also tried this:

public function roles()
{
    return $this->belongsToMany(Role::class)->where('role_id, '!=', $id);
}

Any idea how to do this or if it's even possible?

Thanks!


Solution

  • You should try using a Scope on the Roles model.

    You could create a Scope called DisplayRole which basically returns all Roles that do not include superadmin and are ok to display to the user. It would look something like this:

    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class DisplayRole extends Role
    {
        public function newQuery($excludeDeleted = true)
        {
            return parent::newQuery($excludeDeleted)->where('name','!=','superadmin');
        }
    }
    

    Then you can just use DisplayRole the same way you would normally use a model (use App\DisplayRole) and any place that you need to only show the user-friendly roles, use that model instead of the base Role model. That way, calling DisplayRole::all() will return all roles that are not superadmin.