- Published on
How to prepare input before validation in laravel
- Authors
- Name
- Karani John
- @MKarani_
I was dealing with a problem yesterday and wanted something custom to prepare input for validation and change it to maintain a cleaner controller. So what did I do? Checked the laravel docs for that specific problem? Can I change the input value somewhere else before it hits the controller? Turns out, I can change the input before validation.
How ?
So, Let's say you have a user friendly application allowing for all kinds of values eg. Yes instead of true. It is common to make sure that once things hits the database, you want to ensure that its changed to true. This way you ensure that you don't go about hard coding values.
Laravel provides this simple method in the FormRequest.
protected function prepareForValidation(): void
{
}In this method, you can perform these changes and then you can merge the changes to the request data. eg:
protected function prepareForValidation(): void
{
$this->merge([
'is_resident' => $this->normalizeYesNo($this->input('is_resident')),
]);
}
protected function normalizeYesNo($value)
{
return match (strtolower($value)) {
'yes' => true,
'no' => false,
default => $value,
};
}This way you can validate on booleans and handle things as booleans from there, all the way down to the data layer. Also it abstracts some of that logic away from your controller.
For me, my use case was allowing the user to pick a type that could be matched to an enum::getclass to maintain relationships in the database. This was a nice way to ensure cleanliness in your code.
Other use cases include:
- Trimming strings
- Parsing types eg. Dates
- Defaulting missing values,
- Cleaning noise etc
Its a nice to clean up.
I just want to validate first,
If you want to do things after you have validated them, you can normalize them after its validated eg. say you are checking ['required', 'in:yes,no], then you can normalize after its checked in the form request method :
$validated = $request->validate([
'is_resident' => ['required', 'in:yes,no'],
]);
$validated['is_resident'] = match (strtolower($validated['is_resident'])) {
'yes' => true,
'no' => false,
default => null,
};That way, you can still use your validation as but move some of the logic you may have in your controller to your form request.
Cheers!