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

jrdavidson's avatar

Select Option Groups

I currently have the following query where I grab all users that have a role of 1,2,3 in the database. I grab their first name and last name and id for the sole purpose of a select box. What I'm wanting to do is with the ids that I pass in the whereIn to also grab the role name so I can use it for creating option groups.

$options = \App\User::whereHas('roles', function ($query) {
                $query->whereIn('id', [1, 2, 3]);
            })->get()->map(function ($user) {
                $user->name = $user->first_name . ' ' . $user->last_name;
                return $user;
            })->pluck('name', 'id');
0 likes
11 replies
tisuchi's avatar

@xtremer360

Can try with following code-


$userId = \App\User::where('your-table-colum-field')
                ->lists('id')->toArray();


$userDetails = \App\User::whereIn('id', $userId)
                ->get();
Snapey's avatar

Won't your option groups be a separate list to the users?

jrdavidson's avatar

What I am trying to do is get 3 roles with the ids and then for each of them get the uses that are inside those roles and use the role name as the option group.

Snapey's avatar

then why not

$roles = Roles::with('users')->whereIn(1,2,3)->get();

and then you can automatically access $role->name

1 like
jrdavidson's avatar

@Snapey Will that work for a select dropdown for options though?

As a remind this is my current query.

$options = \App\User::whereHas('roles', function ($query) {
    $query->whereIn('id', [1, 2, 3]);
})->get()->map(function ($user) {
    $user->name = $user->first_name . ' ' . $user->last_name;
        return $user;
})->pluck('name', 'id');

Keep in mind that this my table structure.

Users Table- id, first_name, last_name Role_User Table = role_id, user_id Roles Table - id, name

I'm trying to do the following as an example.

<select name="assign_id">
    <optgroup label="Admins">
            <option value="1">John Smith</option>
            <option value="2">Jane Smith</option>
    </optgroup>
    <optgroup label="Editors">
            <option value="3">Brian Smith</option>
            <option value="4">Scott Smith</option>
    </optgroup>
    <optgroup label="Basic Users">
            <option value="3">Kevin Smith</option>
            <option value="4">Tanya Smith</option>
    </optgroup>
</select>
darrentaytay's avatar
Level 1

Flip it on it's head.

Rather than trying to find Users, then map them to the Role, find the Role, then find the associated Users with each role.

        $options = \App\Role::whereHas('users', function ($query) {
            $query->whereIn('roles.id', [1, 2, 3]);
        })->get()->map(function ($role) {
            $users = $role->users->map(function($user) {
                return sprintf('%s %s', $user->first_name, $user->last_name);
            })->toArray();

            return ['role' => $role->name, 'users' => $users];
        })->keyBy('role')->map(function($user) {
            return $user['users'];
        });

This will give you an array which looks like;

Role A
- User 1
- User 2
Role B
- User 3
- User 4

You'd be able to plug that straight into the Form package and generate that markup you posted.

2 likes
Snapey's avatar

My query should have given you what you need, and with eager loading.

roles 1,2 or 3 with the users for each role and access to the name

1 like
gottaluvkd's avatar

@darrentaytay I'm trying to do something similar, but in addition to just the first_name, last_name, what if I want to include the user_id as the key to the name?

My intention is to use Form::select() and have it like this:

Role A

<option value="101">User 1</option>

Role B

<option value="194">User 2</option>

...

Snapey's avatar

@gottaluvkd please use three backticks ``` before and after code blocks so that we can see your code

Please or to participate in this conversation.