Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Beechey's avatar

Find user roles

So I just finished Jeffrey's short ACL tutorial on the 5.1 update series, and I'm wondering how to go about listing all users, along with their roles in the view. Likely with something like $user->roles()->label as it loops through a list of all users to output them (or a 'getRole()' function if possible).

Also, since I want my users to be defaulting to role_id of 4 ('member'), how would I go about doing that upon their registration?

Been staring at this project for so long it is beginning to drive me crazy, I think.

Thanks very much!

0 likes
15 replies
jlrdw's avatar

You can do that like you would foreach any database records.

Beechey's avatar

@jlrdw So is it just not possible at all? If not I can just list the user's role ID, but having a more readable value would be preferable.

DarkRoast's avatar

Something like this:

$users = $user->with('roles')->get();

foreach ($users as $user)
{
    echo $user->username;

    foreach ($user->roles as $role)
    {
        echo $role->id;
        echo $role->name;
    }
}

edit: For assigning a role to the user (assuming you are using the AuthController that Laravel generates and the HasRoles trait in Jeffs example) you can just do $user->assignRole('member'); after creating that users account.

1 like
jlrdw's avatar

That's what I said like you would iterate any database records. I just said foreach instead of iterate.

Beechey's avatar

I'm sure I can, I mean I'm just missing how I would. Obviously I'd do something like

@foreach ($users as $user)
    <p>{{ $user->roles()->label }}</p>
@endforeach 

But I just can't, for the life of me figure out how. That code above, which I thought would work, returns the error:

Undefined property: Illuminate\Database\Eloquent\Relations\BelongsToMany::$label

I've been looking at this for so long with very little to show for it, I feel like I'm now a professional tunnel-visioner.

jlrdw's avatar

You do have your models that controllers all set up correctly right.
If by chance you are new to this I highly suggest you take the intermediate tutorial that's built right into the documentation.

Beechey's avatar

@jlrdw To Laravel, and any framework of this size? Relatively, yes. But don't get me wrong, I've done lots of looping through tables to grab data, I think I'm struggling with this because it's using a pivot table (never had to use one), so it's possible my models might not be as they should, although I did it exactly as Jeffrey did on his video series.

For example, the Users table has the role_id, which I can get very easily, obviously. But I want the role's label (professional name), so to get that, I thought I needed to go through my 'roles' method in the user model, as I've been doing for everything else, it's just not having any of it. Here's the main points of each model:

User model

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

Role model

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

public function permissions()
{
    return $this->belongsToMany(Permission::class);
}

Permission model

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

And the database (at least the bit we're looking into) is set up like:

  • users
    • role_id
  • roles
    • id
    • label
  • role_user
    • role_id
    • user_id
zachleigh's avatar

$user->roles() returns the relationship, not the role. Youre getting the error because tge relationship has no label property.

jekinney's avatar

On hasMany() and belongToMany unless you grab a single collection, you will by default get a collection of more then one even if you have none or one role. Just how it is. A pivot (technically a connection table as Pivot Table is copyrighted by MS for Excel) just connects a table to a table with the possibility of many relationships/connections. A single role can have many users and a single user can have many roles. An alternative is repeat data or set a json/array on one of the tables, but either way your going to have to loop over the values like I said even if none or one. That is just how it works period end of conversation really.

You can return a single value if it exists, but your still going to have to loop through the results to find it. Many helpers in frameworks do just that by having helper functions. For example the sync() method Loops through and deletes all rows in a pivot table with a column of a certain value and then adds associations by looping through the id's given again in a nice sync() method instead or writing all the code yourself.

Bottom line, it might be hard to grasp, but that is where learning SQL instead of plugging along knee deep with out taking the time to learn about it. Any framework/helpers will loop through the results. Not sure if I said it enough, but just incase, any framework, plugin, helper will have to loop through the results.

jlrdw's avatar

Why Separate Tables just add columns as needed to the user table and keep it simple.

Beechey's avatar

@zachleigh That makes a lot more sense. So would there be a way to retrieve a user roles' label?

Doing

public function getRole()
{
    dd($this->roles);
}

Returns a collection, which includes my user's role attributes, such as

"id" => 3
"name" => "admin"
"label" => "Administrator"
"created_at" => null
"updated_at" => null
zachleigh's avatar
Level 47

@Beechey $user->roles is the property and $user->roles() is the relationship. The property should give you a collection of roles, so you can iterate over the collection and get the label for the individual roles.

$roles = $user->roles;

foreach ($roles as $role) {
    echo $role->label;
}
1 like

Please or to participate in this conversation.