Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SYPOMark's avatar

Complex Conditional Validation of form Request

Hi there,

I hope that somebody can help with this issue.

I've read in the Laravel Docs that you can add conditional rules to validation. The example given is to do with adding a requirement to a given field only if another field has a value greater than 100. In their example, if an owner has more than 100 games, then the application should request a reason, like so:

use Illuminate\Support\Fluent;

...

$v = Validator::make($data, [
    'email' => 'required|email',
    'games' => 'required|numeric',
]);

$v->sometimes('reason', 'required|max:500', function ($input) {
    return $input->games >= 100;
});

I'd like to leverage this functionality, but am not sure how to do it to fit our use case. This is what I am after:

I have a form with a few fields in it, the first being a dropdown of categories of things and the last being a date picker to add a purchase date. The table that populates the categories dropdown has among it's columns: name and purchased (ENUM, 'y','n'). Some of the category names relate to gifts, so would not be purchased by the user.

So, a couple of the rows in the categories table might include Bought as Reward for name, and y for purchased and secondly, Given by Parents for name and n for purchased.

When the user comes to complete their form to log their things, if they've chosen, Given by Parents as their category, the purchased date should not be required, but it should be required if they choose Bought as Reward.

I think I'm probably going to have to use a sometimes rule to make this work, I am just not sure how. Any help that anybody can provide would be most appreciated.

Hopefully the example I have provided of what I am after makes sense, if not, please ask for clarification.

With kind regards,

Mark

0 likes
3 replies
SYPOMark's avatar
SYPOMark
OP
Best Answer
Level 1

Hi there,

Not sure why this one didn't attract any responses. Maybe because the answer was so easy to work out, most people thought, 'He'll get there in the end.'

Well, I did! I thought I'd put this up here in case anybody else gets stuck on a similar issue and comes across this post in their Googling.

This is some of what I put in my ThingRequest.php file:

...
use Laravel\Spark\ThingType;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Http\FormRequest;

class ThingRequest extends FormRequest
...
public function validator()
{
    $thingCatId = FormRequest::get('thing_cat_id');
    $thingCatName = ThingType::where('id', $thingCatId)->value('name');
    $required = ThingType::where('id', $thingCatId)->value('purchased');

    if ($required == 'y') {
        return Validator::make($this->all(), [
            'thing_cat_id' => 'required',
            'purchase_date' => 'required|date_format:d/m/Y',
            'notes' => 'max:255',
        ], $this->messages());
    }
    else {
        return Validator::make($this->all(), [
            'thing_cat_id' => 'required',
            'notes' => 'max:255',
        ], $this->messages());
    }
}

If anyone reads this and thinks, 'I know a more elegant solution to this!' please add it.

With kind regards,

Mark

gregokninski's avatar

The rules are just an array so you can build them up externally to the Validator call:

// create array with common rules
$rules = [
    'field' => 'required'
];

// conditional rule
if (something) {
    $rules['field2'] = 'required';
}

// call validator
$validator = Validator::make(
    $request->all(),
    $rules
);
james.ratcliffe's avatar

If the only thing that changes is the array of rules, you can overwrite the rules() method instead to keep things a bit simpler:

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Validator;
use Laravel\Spark\ThingType;

class ThingRequest extends FormRequest
{
    public function rules(): array
    {
        $rules = [
            'thing_cat_id' => 'required',
            'notes' => 'max:255',
        ];

        $thingCatId = FormRequest::get('thing_cat_id');
        $thingCatName = ThingType::where('id', $thingCatId)->value('name');
        $required = ThingType::where('id', $thingCatId)->value('purchased');

        if ($required == 'y')
        {
            $rules['purchase_date'] = 'required|date_format:d/m/Y';
        }
        
        return $rules;
    }
}

Please or to participate in this conversation.