1

I am trying to add custom validation in my controller.

<?php

namespace App\Http\Controllers;

use Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Redirect;
use Response;
use Validator;

class MyController extends Controller
{

    public function store(Request $req)
    {

        $v = Validator::make($req->all(), [
          'contract_ref' => 'required'
        ]);

        $v->after(function($v) use(&$req){
            dd('custom validations');

            // list of custom validations
            if ($req->div_id == '') {
                $validator->errors()->add('div_id', 'Please select a Division');
            };
        });

        dd('NO!');

        if ($v->fails()) {
         //
        }

        $v->validate();
    }

}

However, for some reason I don't understand. Nothing in the -after closure is being done. In example above, I get "NO!" dumped instead of the expected "custom validations"

This ->after has worked for me previously and I don't get why it is not working here.

11
  • try php artisan optimize:clear.at first attempt even for me also same think happened but after running optimize command then it started working Commented Aug 15, 2022 at 17:29
  • @JohnLobo no change. Commented Aug 15, 2022 at 18:31
  • which version of Laravel (though it should make much a difference)? Commented Aug 15, 2022 at 19:44
  • 1
    @happymacarts 8.4 Commented Aug 15, 2022 at 19:51
  • 1
    it doesn't do the validation until fails (which calls passes) is called here, so the after closure wouldn't be called before your dd as validation hasn't happened yet Commented Aug 16, 2022 at 0:27

3 Answers 3

2

Your are requesting dd('NO!') before the actual validate

try this :

<?php

namespace App\Http\Controllers;

use Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
use Redirect;
use Response;
use Validator;

class MyController extends Controller
{

    public function __contruct()
    {
    }

    public function store(Request $req)
    {

        $v = Validator::make($req->all(), [
            'contract_ref' => 'required'
        ]);

        $v->after(function ($v) use (&$req) {
            dd('custom validations');

            // list of custom validations
            if ($req->div_id == '') {
                $validator->errors()->add('div_id', 'Please select a Division');
            };
        });


        if ($v->fails()) {
            //
        }

        $v->validate();
        dd('NO!');
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

doh! Worst of all @happymarts actually asked if this was the problem but I thought it wasn't the issue.
1

I reccomend using Closures https://laravel.com/docs/8.x/validation#using-closures as it can keep all of your validation logic in one place

use Illuminate\Support\Facades\Validator;

$validator = Validator::make($request->all(), [
  'title' => [
    'required',
    'max:255',
    function ($attribute, $value, $fail) {
        if ($value === 'foo') {
            $fail('The '.$attribute.' is invalid.');
        }
    },
  ],
]);

1 Comment

This was a useful solution but did not answer the question as posted. It turns out I was wrong in my response to you regarding when the after gets called and that as indeed the problem. Someone else posted it as an answer so I am going to accept that one. Thanks for your help.
0

Have you used that?

$v->validate();

Below is an example of validation. You can also check your invalid input values inside fail check.

        $validation_array = [
            'id' => 'required',
            'date' => 'required|date',
            'material_type' => 'required',
            'fabric' => 'required_if:material_type,==,0',
            'color' => 'required_if:material_type,==,1',
            'quantity' => 'required|numeric',
            'unit' => 'required',
        ];

        $validation_messages_array = [
            'fabric.required'    => 'The fabric field is required when material type is fabric.',
            'color.required_if' => 'The color field is required when material type is blind.'
        ];

        $validator = Validator::make(
            $request->all(),
            $validation_array,
            $validation_messages_array
        );

        $validator->after(function ($validator) {
        });

        if ($validator->fails()) {
            //code if not valid
        }

        $validator->validate();

9 Comments

that makes no difference. Remember my point is that the code before inside of the after is not being used for some reason. The initial validation rules are there... but just nothing from the after
Can you share those rules?
I have added rules above, but it doesn't matter what rules are in there, or if there are actually rules or not. No matter what I try, I can't get the after to fire.
Well, actually, we also need to see your class (including inherited class, validation trait) in which you use validation
now I am lost as to what you need to see. Should the code that I have not above not work by itself? All I have is use Validator. Why would I need anything else to stop that block of code from being ignored?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.