Table of Contents
Here’s one of those Laravel features that’s been around forever but still doesn’t get the love it deserves: prepareForValidation().
If you’ve ever written gnarly conditional validation rules just because the incoming form data was messy, this one’s for you.
The Problem
Say you have a pricing form where users can pick different plan tiers. The form sends data keyed by the tier number they selected. But your validation rules really only care about the final, normalized value β always stored against tier 1.
You could write a pile of conditional rules to handle every possible tier. Or you could just normalize the data before validation even runs.
The Fix
Laravel’s FormRequest class has a prepareForValidation() method that fires right before your rules() are evaluated. Use it to reshape incoming data so your rules only deal with a clean, predictable structure:
class UpdatePricingRequest extends FormRequest
{
protected function prepareForValidation(): void
{
$tiers = (array) $this->get('tiers');
foreach ($tiers as $tierName => $tierData) {
$selectedTier = $tierData['selected_tier'] ?? 1;
if ($selectedTier > 1) {
// Copy the selected tier's value to tier 1
$this->merge([
"prices.{$tierName}.1" => $this->input("prices.{$tierName}.{$selectedTier}"),
]);
}
}
}
public function rules(): array
{
return [
'prices.*.1' => 'required|numeric|min:0',
];
}
}
Why This Works
Your validation rules only need to care about one shape: prices.*.1. The real-world messiness β users picking tier 3 on one plan and tier 7 on another β gets handled upstream, before rules even see it.
This keeps your rules dead simple and your normalization logic in one obvious place. No more spreading data transformation across rules, controllers, or middleware.
When to Reach For It
Any time your incoming data doesn’t match the shape your rules expect. Common cases:
- Trimming or lowercasing string fields
- Remapping aliased keys from different API consumers
- Setting defaults for optional fields
- Normalizing nested data like the tier example above
The official docs cover it briefly, but once you start using it, you’ll wonder how you ever managed without it.

Leave a Reply