skip to Main Content

I have a paginated route that requires a perPage attribute. The value must be greater than 10 but smaller than 100. If it doesn’t pass validation, my request sets perPage to 10. I’ve tried this so far, and it works, but I think it’s not the right way to do it.

why I think it is wrong? Because if you send a string in perPage attribute it returns a validation error

class PaginateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }
    
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, IlluminateContractsValidationValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'perPage' => 'nullable|numeric|min:10|max:100',
        ];
    }
    
    protected function prepareForValidation()
    {
        $this->merge([
            'perPage' => (!isset($this->perPage) || $this->perPage < 10 || $this->perPage > 100) ? 10 : $this->perPage,
        ]);
    }
}

3

Answers


  1. Looking at your requirement, you don’t need the Form Request Validation. You can handle it in the controller itself by simply set the default value to your request variable.

    One way will be using $request->input() along with condition to handle the min max of the prePage you need. It can be either a if condition or using min max function of PHP

    $prePage = $request->input('perPage', '10');
    
    // Adjusting the value based
    if ($prePage < 10 || $prePage > 100) {
        $prePage = 10;
    }
    
    // Using min and max function
    $prePage = min(max($prePage, 100), 10);
    
    Login or Signup to reply.
    1. Simply, you can avoid validation and take perPage from request intead.
    2. Another way, you just have to remove ‘numeric’ from rules.

    The first one is more efficient.

    Login or Signup to reply.
  2. you can modify your condition to ignore non numeric values:

    $this->merge([
      'perPage' => ($this->isNotFilled('perPage') || !is_numeric($this->perPage) || $this->perPage < 10 || $this->perPage > 100) ? 10 : $this->perPage,
    ]);
    

    however I should add that, this behaviour is confusing for someone consuming this endpoint, example: someone requests 200 records, but gets only 10 with very little to no indication as to why.

    Better you should remove this merge from the form request, and handle the nullable value in your controller as $request->input('perPage', config('pagination.default'))

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search