Мне нравится этот запрос, который работает на простом sql:

SELECT users.id, users.name, roles.name
FROM users
LEFT JOIN model_has_roles ON model_has_roles.model_id = users.id
LEFT JOIN roles ON roles.id = model_has_roles.role_id
ORDER BY roles.name ASC

Используя laravel, я пробовал вот так, но это не сработало:

$user = $request->user();

$role = (array) $request->get('role', []);
$order = (array) $request->get('order');

$perPage = $request->get('perPage') ?? 10;

$users = User::where('id', '!=', $user->id);

if(count($role)) {
    if (($key = array_search('admin', $role)) !== false) {
        unset($role[$key]);
    }
    $users = $users->whereHas('roles', function ($query) use($role) {
        return $query->whereIn('name', $role);
    });
} else {
    $users = $users->whereHas('roles', function ($query) {
        return $query->whereIn('name', ['farmer', 'specialist', 'company']);
    });
}

if(count($order) && isset($order['field'])) {
    $orderType = $order['type'] ?? 'ASC';
    if($order['field'] == 'role') {
        $users = $users->leftJoin('model_has_roles', 'model_has_roles.model_id', '=', 'users.id')
        ->leftJoin('roles', 'roles.id', '=', 'model_has_roles.role_id')
        ->orderBy('roles.name', $orderType);
    } else {
        $users = $users->orderBy($order['field'], $orderType);
    }
}

$users = $users->paginate($perPage);

Сообщение об ошибке:

`"message": "SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous (SQL: select count(*) as aggregate from `users` left join `model_has_roles` on` `model_has_roles`.`model_id` = `users`.`id` left join `roles` on `roles`.`id` = `model_has_roles`.`role_id` where `id` != 3 and exists (select * from `roles` inner join `model_has_roles` on `roles`.`id` = `model_has_roles`.`role_id` where `users`.`id` = `model_has_roles`.`model_id` and `model_has_roles`.`model_type` = App\\Models\\User and `name` in (specialist, company)))",
1
Andreas Hunter 10 Фев 2021 в 11:24

1 ответ

Лучший ответ

Поскольку обе ваши модели имеют идентификатор, и после выполнения sql столбец идентификатора запроса будет неоднозначным, поэтому это поможет вам:

$users = User::where('id', '!=', $user->id);

изменить на

$users = User::where('users.id', '!=', $user->id);

Тогда попробуйте:

$users = $users->select(['users.id', 'users.name', 'roles.name'])
                ->leftJoin('model_has_roles', 'model_has_roles.model_id', '=', 'users.id')
                ->leftJoin('roles', 'roles.id', '=', 'model_has_roles.role_id')
                ->orderBy('roles.name', 'ASC');
1
Andreas Hunter 10 Фев 2021 в 08:43