Introduction
Laravel’s Form Requests are a great way of removing validation logic from your controllers.
There are times were it can be useful to update or change the request data before it is passed to the validator for example formatting postcodes, removing invalid characters or providing default values to data.
The official documentation shows how we can perform additional logic after the rule sets have been run but not before hand.
Digging through the Form Request api there is mention of a method called prepareForValidation
which is an empty method that is called before the actual validation rules are run as can be seen in implementation:
So given that the method is empty how do we use it and go about updating the form request data?
Solution and example of implementation
The merge
method on the same class is how.
Here’s an example of something I was working on recently.
We had built a Laravel app that is accessed by a React Native application. Our client realised post launch that they needed to only run certain validation against driving licences from Great Britain only. They said that almost all of their clients have GB licences but they still need to be able to accommodate others.
So we amended the validation rules for this particular request to accommodate this new indicator:1
2
3
4
5
6
7
8// Form request class...
public function rules()
{
return [
...
'gb_licence' => ['required', 'bool'],
];
}
However it takes time apps to get reviewed and published into their respective app stores and even then being in the app store doesn’t ensure that all clients are using the latest version of that app.
So rolling this code out would break our existing clients since they would fail the required
rule.
We could have versioned off the API so that old versions of the app call the old code but newer build call a new route with this new validation, however for such a minor change it felt like overkill. Also it would still mean we’d have to create a default value for older clients otherwise we’d end up with not null errors with our database.
So for the following reasons we opted to create a default value for this gb_licence
indicator.
- We could continue to use the existing API (didn’t require the API to be versioned)
- We could roll the code immediately without impacting existing clients
- It would work as soon as the apps in either store were released
And this is all it took:1
2
3
4
5
6
7// Form request class...
protected function prepareForValidation(): void
{
$this->merge([
'gb_licence' => $this->gb_licence ?? true,
]);
}
So in this instance if the gb_licence
field didn’t exist it would be created and given a default value of true
.
Super easy!
I’ve used the prepareForValidation
in a number of different FormRequests when needing to pre-format incoming data. A common example being uppercasing and formatting postcodes and vehicle registration numbers:
1 | // Form request class... |
I actually use a number of custom helper functions to actually do this but the above should illustrate how you can amend existing data.