Search code examples
laravellaravel-8laravel-request

Merge Form Request Validation for store and update


I am using Request validation to validate the user's input.

This is 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',
        ];
    }
}

As you can see, there is some update-specific stuff happening:

The authorize() method checks whether the user is allowed to update-user and inside the rules I am excluding the row of the current user from being unique:

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

As I would like to merge UpdateUser and StoreUser, what would be the most efficient and readable way to determine, whether I am updating or saving?

This is my current approach:

<?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');
    }
}

I am wondering if I may extend the FormRequest class and provide isUpdating() by default.


Solution

  • Your update and store method are not the same request type, you have PUT and PATCH method on your request instance, so you can check the request type as like :

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