Проверка запроса формы слияния для хранилища и обновления

#laravel #laravel-8 #laravel-request

#laravel #laravel-8 #laravel-запрос

Вопрос:

Я использую проверку запроса для проверки ввода пользователя.

Это UpdateUser :

 <?php

namespace AppHttpRequests;

use IlluminateFoundationHttpFormRequest;
use IlluminateSupportArr;
use IlluminateSupportFacadesGate;

class UpdateUser extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return Gate::allows('update-user');
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {

        $user_id = Arr::get($this->request->get('user'), 'id');

        return [
            'user.firstname'      => 'required|string|max:255',
            'user.lastname'       => 'required|string|max:255',
            'user.email'          => "required|string|email|max:255|unique:users,email,{$user_id}",
            'user.password'       => 'sometimes|nullable|string|min:4|confirmed',
        ];
    }
}
 

Как вы можете видеть, происходит что-то update конкретное:

authorize() Метод проверяет, разрешено ли пользователю update-user входить и находиться внутри rules I, исключая строку текущего пользователя из уникальности:

 'user.email'          => "required|string|email|max:255|unique:users,email,{$user_id}",
 

Поскольку я хотел бы объединить UpdateUser и StoreUser , что было бы наиболее эффективным и читаемым способом определить, обновляю я или сохраняю?

Это мой текущий подход:

 <?php

namespace AppHttpRequests;

use IlluminateFoundationHttpFormRequest;
use IlluminateSupportArr;
use IlluminateSupportFacadesGate;

class UpdateUser extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        if($this->isUpdating())
        {
            return Gate::allows('update-user');
        }

        return Gate::allows('create-user');
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        if($this->isUpdating()){
            $user_id = Arr::get($this->request->get('user'), 'id');

            return [
               ...
            ];
        }

        return [];
    }
    
    /**
     * @return bool
     */
    protected function isUpdating(){
        return $this->isMethod('put') || $this->isMethod('patch');
    }
}
 

Мне интересно, могу ли я расширить класс FormRequest и предоставить isUpdating() по умолчанию.

Комментарии:

1. asklagbox.com/blog/form-request-store-update

Ответ №1:

Ваш метод update и store — это разные типы запросов, у вас есть PUT PATCH метод and в вашем экземпляре запроса, поэтому вы можете проверить тип запроса следующим образом :

 switch ($request->method()) {
   case 'PATCH':
        // do anything in 'patch request';
        break;

   case 'PUT':
        // do anything in 'put request';
        break;

   default:
       // invalid request
       break;
}
 

Ответ №2:

Некоторое время назад я узнал о новом подходе к проверке, используя отдельный класс validator, и мне это очень нравится. Позвольте мне показать вам

Создайте каталог Validators и класс внутри UserValidator

 class UserValidator
{
    public function rules(User $user)
    {
        return [
            'user.firstname' => [
                'required',
                'string',
                'max:255',
            ],

            'user.lastname' => [
                'required',
                'string',
                'max:255',
            ],

            'user.email' => [
                $user->exists ? 'sometimes' : null,
                'required',
                'string',
                'email',
                'max:255',
                Rule::unique('users', 'email')->ignore($user->exists ? $user->id : null)
            ],

            'user.password' => [
                $user->exists ? 'sometimes' : null,
                'required',
                'string',
                'min:8'
            ],
        ];
    }

    public function validate(array $data, User $user)
    {
        return validator($data, $this->rules($user))            
            //->after(function ($validator) use ($data, $user) {
            //    Custom validation here if need be
            //})
            ->validate();
    }
}
 

Затем авторизация может быть выполнена в контроллере

 class UserController
{
    use AuthorizesRequests;

    /**
     * @param Request $request
     */
    public function store(Request $request)
    {
        $this->authorize('create_user', User::class);

        $data = (new UserValidator())->validate(
            $request->all(),
            $user = new User()
        );

        $user->fill($data)->save();
    }

    /**
     * @param Request $request
     * @param Appuser $user
     */
    public function update(Request $request, User $user)
    {
        $this->authorize('update_user', $user);

        $data = (new UserValidator())->validate(
            $request->all(),
            $user
        );

        $user->fill($data)->save();
    }
}
 

Это было предложено и объяснено (ручкой twitter) @themsaid