Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

617
Views
Validate a field only if another one passes validation (in Laravel 8)

I have a problem, how do you add / remove a rule if another rule passed/fails?

public function rules()
{
    $rules = [
        'description' => 'required|unique:orders,description',
        'user_id' => 'required|unique:users,id',
        'supplier_id' => 'required',
        'warehouse_id' => 'required|unique:warehouse,id',
        'warehouse_qty' => 'required'


    ];
    
    return $rules;
}

For example, if the "warehouse_id" rule fails, it would not be necessary to evaluate the "warehouse_qty" field's rules (since the warehouse id is not found in the db).

Or if the "user_id" field's rule succeeds, new rules should be activated, like for "user_name" and "user_phone" fields.

Thanks!

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

To validate a field only if another passes validation, there are multiple solutions.

Approach #2 (recommended)

Since Laravel 5.3.23; Simply move any field validation that depends on another field's rules, into Controller's withValidator(...) method, like:

use Illuminate\Support\Facades\Validator;

// ...

public function withValidator($validator)
{
    $validator->after(function ($validator) {
        // Skip if any previous field was invalid.
        if ($validator->failed()) return;

        // Actual validation (for fields depending on previous).
        Validator::make($this->input(), [
            'warehouse_qty' => ['required']
        ])->validate();
    });
}

This has the advantage of simply using existing rules, as you would normally (instead of rewriting the "required" rule's source-code, which the below approach does).

See also related Laracast post.

Note that if rules() method is not defined, withValidator(...) is never called (and calling $this->input() may result in function not defined error).

Approach #1 (Old answer)

Since Laravel 5.6 and later we can do below:

use Illuminate\Support\Facades\Validator;

// ...

public function rules()
{
    $result = [
        // ...
        'warehouse_id' => 'required|unique:warehouse,id',
    ];

    if (Validator::make($this->input(), $result)->passes()) {
        $result['warehouse_qty'] = [
            function ($attribute, $value, $fail) {
                if (empty($value)) {
                    $fail('The '.$attribute.' is required.');
                }
            },
        ];
    }

    return $result;
}

Note that for above to work, the fields order is important, and the closure should be added to array right after the fields it is depending on.

-------===-------

While above are custom approaches (for asked matter), doing that for rules of the same field is built-in Laravel.

  1. Adding a rule if another rule passed is easy:
    • The rules are executed from left to right.
    • Use pipe (the | character) to separate rules.
    • And, as long as rules at left pass, the later rules are added and/or executed.
  2. Removing a rule if another rule fails can be achieved by pipe as well.

    Simply because any rule after the failed one is ignored.

  3. But the reverse of above two statements is not possible:
    • We can not add and/or execute next-rule if previous fails.
    • We can not remove next-rule if previous passed.
    • At least, not without custom function.
over 4 years ago · Santiago Trujillo Report

0

Thanks to all who gave their solutions to my problem, especially Top-Master, since his explanation showed me another point of view.

I was finally able to solve my problem, and this is my solution. If anyone can improve the code, it is welcome.

public function rules()
{   

    $rules = [
        'description' => 'required|unique:orders,description',
        'user_id' => 'required|unique:users,id',
        'supplier_id' => 'required'
    ];
  
    $rules = $this->validateItems($rules);
    
    return $rules;
}

public function validateItems($rules){


        $rules["warehouse_id"] = ['required', 
                                  'unique:warehouse,id'];
        
        //Here I validate if the rules of the "warehouse_id" field fail or not.
        $validator = Validator::make($this->input('warehouse_id'), [
            "id" => ['required', 
                     'unique:warehouse,id']
        ]);

        //If the validation doesn't fail, the "warehouse_qty" field is added to $rule                                 
        if(!($validator->fails())){
            $rules["warehouse_qty"] = ['required'];
        }
        
    }
    return $rules;
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!