LARAVEL

Laravel Form Request Validation Guide

February 10, 2024 13 min read

Introduction

Form Requests are a powerful Laravel feature that encapsulates validation logic in dedicated classes. They keep your controllers clean and provide built-in authorization checks.

Creating Form Requests

Generate a form request class:

php artisan make:request StorePostRequest

The generated class:

// app/Http/Requests/StorePostRequest.php
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'title' => 'required|string|max:255',
            'content' => 'required|string',
            'category_id' => 'required|exists:categories,id',
        ];
    }
}

Validation Rules

public function rules()
{
    return [
        'title' => 'required|string|min:5|max:255|unique:posts,title',
        'slug' => 'required|string|alpha_dash|max:255|unique:posts,slug',
        'content' => 'required|string|min:10',
        'featured_image' => 'nullable|image|max:2048',
        'published_at' => 'nullable|date|after_or_equal:today',
        'tags' => 'array',
        'tags.*' => 'exists:tags,id',
        'metadata.title' => 'nullable|string|max:70',
        'metadata.description' => 'nullable|string|max:160',
    ];
}

Authorization

// app/Http/Requests/UpdatePostRequest.php
class UpdatePostRequest extends FormRequest
{
    public function authorize()
    {
        $post = $this->route('post');
        
        // Check if user owns the post
        return $post && $this->user()->can('update', $post);
    }
}

Using Laravel Policies:

// In your Policy
public function update(User $user, Post $post)
{
    return $user->id === $post->author_id || $user->is_admin;
}

Customization

// Custom messages
public function messages()
{
    return [
        'title.required' => 'A title is required for your post.',
        'title.unique' => 'This title has already been taken.',
        'content.min' => 'Post content must be at least :min characters.',
    ];
}

// Custom attributes
public function attributes()
{
    return [
        'featured_image' => 'cover image',
        'metadata.title' => 'SEO title',
    ];
}

// Prepare data before validation
protected function prepareForValidation()
{
    if (!$this->slug && $this->title) {
        $this->merge([
            'slug' => Str::slug($this->title)
        ]);
    }
}

Summary

Form Requests in Laravel provide a clean way to organize validation logic and authorization checks. They keep controllers lean while providing powerful features like custom messages, attribute names, and data preparation.

For more information, check out our other tutorials on Route Model Binding and Mailables.