I personally think that one of the most underrated feature of Laravel is Form Request. Form Requests allows you to perform more complex authorizations and validations and can drastically clean up your controllers if you know how to use it.
Here are 3 things you probably did not know you can do with Form Requests.
1. Removing the authorize method will make the authorization check pass.
When generating Form Requests using php artisan make:request FooRequest
command , the authorize method by default will return false. However, instead of returning true in this method, you can just delete it entirely - which achieves the same result and a much cleaner approach.
2. Add a persist method in Form Request class to handle storing and updating of your models.
Basically, we will let our form persist itself. Lets take a look at this simple blog post example:
// In our PostRequest class we can have the following methods.
class PostRequest {
public function rules()
{
return [
'title' => 'required|max:255',
'body' => 'required',
];
}
public function persist(Post $post = null) // We type-hint our Post model here.
{
$post = $post ?? new Post;
$post->title = $this->title;
$post->body = $this->body;
$post->save();
return $post->fresh();
}
}
// In our PostController we can have the store and update methods like so.
class PostController extends Controller
{
public function store(PostRequest $request)
{
// You can definitely return view or redirect here, whichever you prefer.
// Let's assume this is a json endpoint so we just return PostResource.
return PostResource($request->persist());
}
public function update(PostRequest $request, Post $post) // Route-model binding.
{
// We pass the post model so it will be updated in persist method.
return PostResource($request->persist($post));
}
}
Now this cleans up the controller into single-line and we have our validation and persistence layers both within the Form Request class.
3. Before-and-after-validation hooks you can tap into in Form Request class.
If you need to do some logic before the validation runs, such as sanitizing data from the request, you can use the prepareForValidation()
method.
protected function prepareForValidation()
{
$this->merge([
'slug' => Str::slug($this->slug),
]);
}
If you need to do some logic after the validation runs, such as performing further validations, you can use the withValidator(...)
method.
public function withValidator($validator)
{
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'Something is wrong with this field!');
}
});
}
Bonus: Form Request is just an instance of Illuminate\Http\Request
. Which means whatever properties or methods you have access to using the request()
helper, you can also access it in the Form Request class.
For further information about Form Requests, visit the official Laravel documentation here:
https://laravel.com/docs/7.x/validation#form-request-validation
Cheers!