phplaravellaravel-8laravel-authorizationlaravel-formrequest

Reuse FormRequest authorize() for both edit() VIEW and update() METHOD


As per the documentation of Laravel 8, I can create custom FormRequests and put my validation / authorization logic in there. Which works fine for routes like store and update. But before one can actually get to the update route one has to press save on the edit route (the edit view).

So for the edit route. There is nothing to validate (yet), as this is where users enter data into forms for validation (later on). But to decide whether a user can even get to the edit FORM, I could reuse the same logic from the authorize() method in the form.

So how to reuse the authorize() bit from the custom FormRequest for the edit view route?

public function authorize()
{
    return $this->user()->can('update', $this->comment);
}

Or is there no way to do this, and must I rewrite/duplicate the line below?

return $this->user()->can('update', $this->comment);


Solution

  • A solution could be to create a single PostRequest (or whatever name fits your case) and then handle authorization and rules differ depending on which method is being used. While maybe not best practices, it can help reduce code clutter.

    Like the example below, only a POST request would check for a required comment in the validation, while you could still visit the edit and view routes without requiring any validation.

    public function authorize()
    {
        switch ($this->method()) {
            case 'GET':
                break;
            case 'POST':
                $this->user()->can('update', $this->comment);
                break;
            case 'PUT':
                break;
            case 'PATCH':
                break;
            case 'DELETE':
                break;
        }
    
        return true;
    }
    
    public function rules()
    {
        switch ($this->method()) {
            case 'GET':
                return [];
            case 'POST':
                return [
                    'comment' => 'required'
                ];
            case 'PUT':
                return [];
            case 'PATCH':
                return [];
            case 'DELETE':
                return [];
            default:
                return [];
        }
    }