Skip to content
Advertisement

Custom validation not calling the passes() function

I am trying to make a validation that will check whether at least one item is provided in an array following the steps in Custom Validation Rules Routes.php

Route::middleware(['auth:api', 'bindings'])->group(function () {
  Route::prefix('api')->group(function () {
    Route::apiResources([
      'exam-papers/{examPaper}/questions' => ExamPaperQuestionsController::class
    ]);
  });
});

ValidateArrayElementRule.php

namespace AppRules;

use IlluminateContractsValidationRule;

class ValidateArrayElementRule implements Rule
{
  public function __construct()
  {
    //
  }

  public function passes($attribute, $value)
  {
    echo "there";
    return count($value) > 0;
  }

  public function message()
  {
    return 'At least one element is required!';
  }
}

ExamPaperQuestionsController.php

 public function store(ExamPaperQuestionStoreRequest $request, ExamPaper $examPaper)
 {
    return response()->json([])->setStatusCode(201);
 }

In my test file I have

  public function error_422_if_no_questions_provided()
  {
    Permission::factory()->state(['name' => 'create exam paper question'])->create();
    $this->user->givePermissionTo('create exam paper question');
    $this->actingAs($this->user, 'api')
      ->postJson('/api/exam-papers/' . $this->examPaper->id . '/questions', [])
      ->assertStatus(422);

  }

ExamPaperQuestionStoreRequest.php

class ExamPaperQuestionStoreRequest extends FormRequest
{
  /**
   * Determine if the user is authorized to make this request.
   *
   * @return bool
   */
  public function authorize()
  {
    return auth()->user()->can('create exam paper question');
  }

  /**
   * Get the validation rules that apply to the request.
   *
   * @return array
   */
  public function rules()
  {
    echo "HERE";
    return [
      'questions' => [new ValidateArrayElementRule],
      'questions.*.description' => 'required'
    ];
  }


}

The test is failing

Expected status code 422 but received 201.

I can see the text “HERE” is logged but “there” is not. Why is my validation passes() function not being called?

Advertisement

Answer

Suppose if your request contain empty then it wont call custom validation. So you must add required filed to ensure request has key questions

'questions' => ["required",new ValidateArrayElementRule]

Incase questions is optional and if entered then at least two or three item required then you can use required if validation.

By default laravel support min in array

'questions' => ["required","array","min:1"] 
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement