【问题标题】:Merge Form Request Validation for store and update合并表单请求验证以进行存储和更新
【发布时间】:2021-03-07 09:40:01
【问题描述】:

我正在使用请求验证来验证用户的输入。

这是UpdateUser

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;

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-userrules里面我排除了当前用户所在行的唯一性:

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

由于我想合并 UpdateUserStoreUser,确定我是更新还是保存的最有效和可读的方法是什么?

这是我目前的做法:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;

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()

【问题讨论】:

标签: laravel laravel-8 laravel-request


【解决方案1】:

您的 update 和 store 方法不是同一个请求类型,您的请求实例上有 PUTPATCH 方法,因此您可以检查请求类型:

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

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

   default:
       // invalid request
       break;
}

【讨论】:

    【解决方案2】:

    前段时间我了解了一种使用单独的验证器类进行验证的新方法,我非常喜欢它。让我告诉你

    创建目录ValidatorsUserValidator 中的类

    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();
        }
    }
    

    然后就可以在Controller中进行授权了

    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 \App\user $user
         */
        public function update(Request $request, User $user)
        {
            $this->authorize('update_user', $user);
    
            $data = (new UserValidator())->validate(
                $request->all(),
                $user
            );
    
            $user->fill($data)->save();
        }
    }
    

    这是由(推特句柄)@themsaid 提出并解释的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-11
      • 2015-11-07
      • 2015-06-09
      • 2021-04-09
      • 2018-04-07
      • 2014-12-14
      • 1970-01-01
      • 2020-08-15
      相关资源
      最近更新 更多