Правило проверки Laravel UpdateUserRequest с идентификатором пользователя

У меня есть модель User, и это мой метод update() в UserController:

public function update(Request $request, User $user)
{
    // Assign authorization
    Gate::authorize('update', $user);
    
    $request->validate([
        'username' => 'required|unique:users,username,' . $user->id,
        // other rules ...
    ]);
    
    // ...
}

Я хочу сохранить эти правила проверки в отдельном UpdateUserRequest запросе:

class UpdateUserRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true; // Changed to 'true' to handle authorization logic in UserPolicy
    }

    public function rules(): array
    {
        return [
            'username' => 'required|unique:users,username,' . $user->id, // <-- Problem
            // other rules ...
        ];
    }
}

Проблема здесь в том, что $user не определен. Я читал в другом месте, что использование маршрута для этого вопроса является возможным решением, но это не правильный способ решения этой задачи.

Мой вопрос: как правильно передать информацию о пользователе в класс UpdateUserRequest?

У вас есть auth()->user()->id или проще auth()->id()

matiaslauriti 28.08.2024 22:31

@matiaslauriti Что делать, если в систему вошел не тот пользователь?

Zakk 28.08.2024 22:32

@Zakk, можешь ли ты поделиться определением своего маршрута для этого? Используете ли вы неявную привязку модели при определении маршрута?

Subha 29.08.2024 07:13

@Zakk, я опубликовал свой ответ, пожалуйста, проверьте и дайте мне знать ваш отзыв. Спасибо

Subha 29.08.2024 08:00

@Zakk, ты никогда не говорил в своем вопросе, что у тебя может не быть зарегистрированного пользователя...

matiaslauriti 29.08.2024 13:11

@matiaslauriti Какое это имеет отношение к теме? Как эта информация может повлиять на ответ? И с каких это пор вход пользователей в систему или не влияет на другие модели?

Zakk 29.08.2024 13:27

@Закк, откуда я могу знать, что auth()->id() не будет работать, если ты не скажешь мне, что пользователь может существовать? В исходном коде вы получаете пользователя каждый раз...

matiaslauriti 29.08.2024 13:52
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
7
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мой вопрос в том, как правильно передать информацию о пользователе в Класс UpdateUserRequest?

Я предположил, что вы используете laravel 11.X, и ваше определение маршрута...

Route::put('/users/{user}', [UserController::class, 'update']);

В этом сценарии вы можете сделать это внутри UpdateUserRequest.

class UpdateUserRequest extends FormRequest
{
    public function authorize(): bool
    {
        // Here you can also interact with your `gates` & `policy`,Check the docs link I provided below to get clear insights.
        return true; 
    }

    public function rules(): array
    {
        //Scenario 1
        $user = User::find($this->route('user')); //If you are not using `implicit model binding`
        //Scenario 2
        $user = $this->user ; //If you are using `route-model-binding`


        return [
            'username' => 'required|unique:users,username,' . $user->id, // <-- "Issue will be solved"
            // other rules ...
        ];
    }
}

Затем в классе контроллера import и type-hint класс FormRequest, т. е. UpdateUserRequest в вашем методе контроллера, который отсутствует в вашем текущем коде.

public function update(UpdateUserRequest $request, User $user)
{
    // Assign authorization
    Gate::authorize('update', $user);

    // Retrieve the validated input data...
     $validated = $request->validated();  // it will by default validate all the input data you set up in the `rule()` of `UpdateUserRequest`
    
    
    // ...
}

Для получения более четкой и глубокой информации ознакомьтесь с официальной документацией здесь.

Я предпочитаю иметь дело с логикой авторизации в классах политики. В противном случае код будет немного запутанным, поскольку некоторые его части будут находиться в запросах, некоторые — в контроллерах (Gate::authorize()).

Zakk 29.08.2024 09:10

Вот как я определил свои маршруты: Route::resource('users', UserController::class);

Zakk 29.08.2024 09:10

@Zakk, Основная логика останется прежней, и да, вы можете разделить логику авторизации в классах политики, проблем не будет. Если вы используете Route::resource('users', UserController::class);, он по умолчанию будет обрабатывать привязку модели маршрута. Попробуйте ответить и дайте мне знать, если вы где-нибудь застряли. А также перейдите по ссылке на документацию, которую я предоставил в ответе, где вы получите более подробную информацию.

Subha 29.08.2024 09:15

Это сработало. Спасибо! Итак, дело в том, что классы UpdateModelRequest и StoreModelRequest имеют «известную» им модель.

Zakk 29.08.2024 09:28

У меня есть еще два вопроса. Ответ: Необходимо ли использовать validated() для запуска проверки? Или это делается автоматически? Б: Чтобы использовать проверенные данные, можно ли просто использовать $request->username или необходимо использовать функцию validated?

Zakk 29.08.2024 09:33

@Zakk, согласно официальным документам, когда вы используете запрос пользовательской формы, например UpdateModelRequest, вы должны вызвать $request->validated();, чтобы получить проверенные данные. И когда вы используете объект Illuminate\Http\Request по умолчанию, вам нужно использовать $request->validate([ ]) и внутри массива передать все поля проверки в паре ключ-значение массива. проверьте ссылку 1) laravel.com/docs/11.x/… 2) для запроса пользовательской формы проверьте это: - laravel.com/docs/11.x/validation#creating-form-requests

Subha 29.08.2024 09:49

В этом случае, как получить файлы (например, $request->hasFile('field')) по проверенным запросам, поскольку они представляют собой простые массивы?

Zakk 29.08.2024 09:54

«Необходимо ли использовать validated() для запуска проверки» — при использовании запросов формы НЕТ проверка все равно выполняется до того, как будет обработан ваш контроллер, это означает, что ваша проверка выполняется до проверки Gate::authorize. Поэтому авторизацию лучше обрабатывать в самом запросе формы.

kris gjika 29.08.2024 10:04

«Чтобы использовать проверенные данные, можно просто использовать $request->username или они должны использовать проверенную функцию» — вы можете использовать $request->$field, но нет никакой гарантии, что $field было проверено, а использование $request->validated()[$field] приведет к ошибке отсутствия ключа, если $field не был ключевым в списке правил.

kris gjika 29.08.2024 10:06

А как насчет авторизации для других методов, таких как создание и удаление? Должны ли они обрабатываться в контроллере или где-то еще?

Zakk 29.08.2024 10:21

@Zakk, Да, вы можете обрабатывать create и delete так же, как и update. Для создания есть небольшая разница, вы можете проверить эту ссылку 1) laravel.com/docs/11.x/authorization#methods-without-models Для delete вы можете следовать той же логике, что и для update, проверьте ссылку 2) laravel.com/docs/11.x/authorization#policy-methods

Subha 29.08.2024 10:35

Вы не поняли мой вопрос. В случае store и update проверку авторизации лучше выполнять в классах запросов. А как насчет авторизации для create и delete? Должен ли Gate::authorize('create', User::class) присутствовать в методе контроллера create?

Zakk 29.08.2024 10:43

@Zakk, «Должны ли они обрабатываться в контроллере или где-то еще?», вы также можете обработать это в маршруте, используя can() как промежуточное программное обеспечение, а также в контроллере.

Subha 29.08.2024 10:43

В моем случае я не могу использовать can() в качестве промежуточного программного обеспечения, потому что я использую Route::resource('users', UserController::class);

Zakk 29.08.2024 10:45

@Zakk, в этом случае вам нужно использовать метод Gate::authorize('create', User::class) внутри контроллера, возникнет проблема с np. Здесь метод политики create не требует экземпляра модели. Проверьте здесь: - laravel.com/docs/11.x/…

Subha 29.08.2024 11:02

Другие вопросы по теме