Laravel policy missing argument
В политике есть такой код:
public function view(User $user, User $model): bool
{
return ($user->id == $model->id || in_array('read_users', $user->access));
}
Первая модель - авторизированный пользователь, а вторая модель - просматриваемый пользователь. Ничего не работает, тк вторая модель не приходит в политику.
Запускается все в роутинге:
Route::get('/{id}', [UserController::class, 'show'])->name('users.show')->middleware('can:view,' . User::class);
Model binding НЕ используется в контроллере, тк логика работы с бд вынесена в репозитории.
Ответы (1 шт):
У вас есть логическая ошибка. Вы в мидлваре передаете название класса, а в политике проверяете с объектом. Если посмотреть документацию, то Model::class передается в методах политики где не требуется проверка объекта.
Т.е. если не брать мидлвар, а проверять в контроллере, то разница такая:
// Передаете объект, так как требуется проверка объекта
if ($user->can('update', $post)) {
//
}
// передаете название класса, так как объект не нужен при проверке
if ($user->can('create', Post::class)) {
// Executes the "create" method on the relevant policy...
}
В вашей логике, вам нужен в политике объект. Т.е если вашу проверку перенести в контроллер, то будет примерно так:
if($user->can('view', $model)){
}
А что вы передаете в мидлвар? Не объект, а название класса.
Как перенести туда нужный объект? По простому никак, только если писать свой RBAC или делать обертку над дефолтным. Опять таки, в мидлвар вы все равно объект не передадите, но сможете в мидлваре достать параметры из реквеста и уже там создать модель для проверки.
Самый простой путь без костылей и наворотов - делать авторизацию в контроллере.