Elevate Your Laravel Validation with Custom Rules

Elevate Your Laravel Validation with Custom Rules

As Laravel developers, we often encounter scenarios where the built-in validation rules just don't cut it. That's where custom validation rules come in, allowing us to create reusable, testable validation logic for our applications. Let's dive into how to create and use custom validation rules in Laravel.

Why Use Custom Validation Rules?

Custom validation rules offer several benefits:

  1. Reusability across your application
  2. Encapsulation of complex validation logic
  3. Easier testing of validation rules
  4. Cleaner, more readable code

Creating a Custom Validation Rule

Let's create a custom rule for validating strong passwords:

// app/Rules/StrongPassword.php
use Illuminate\Contracts\Validation\Rule;

class StrongPassword implements Rule
{
    public function passes($attribute, $value)
    {
        // Password must be at least 8 characters and contain at least one uppercase letter, one lowercase letter, and one number
        return preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/', $value);
    }

    public function message()
    {
        return 'The :attribute must be at least 8 characters and contain at least one uppercase letter, one lowercase letter, and one number.';
    }
}

Using the Custom Rule

You can use this custom rule in your form requests, controllers, or anywhere you perform validation:

use App\Rules\StrongPassword;

// In a form request
public function rules()
{
    return [
        'password' => ['required', new StrongPassword],
    ];
}

// In a controller
public function store(Request $request)
{
    $request->validate([
        'password' => ['required', new StrongPassword],
    ]);

    // Process the validated data...
}

Advanced Techniques

Parameterized Rules

You can make your custom rules more flexible by accepting parameters:

class MinWords implements Rule
{
    private $minWords;

    public function __construct($minWords)
    {
        $this->minWords = $minWords;
    }

    public function passes($attribute, $value)
    {
        return str_word_count($value) >= $this->minWords;
    }

    public function message()
    {
        return "The :attribute must contain at least {$this->minWords} words.";
    }
}

// Usage
'description' => ['required', new MinWords(5)]

Using Dependencies

If your rule needs to interact with other services or the database, you can use Laravel's service container:

class UniqueInOrganization implements Rule
{
    private $organization;

    public function __construct($organization)
    {
        $this->organization = $organization;
    }

    public function passes($attribute, $value)
    {
        return !User::where('organization_id', $this->organization->id)
                    ->where($attribute, $value)
                    ->exists();
    }

    public function message()
    {
        return 'The :attribute has already been taken within your organization.';
    }
}

Testing Custom Rules

One of the major benefits of custom rules is that they're easily testable:

use App\Rules\StrongPassword;

class StrongPasswordTest extends TestCase
{
    /** @test */
    public function it_passes_for_strong_passwords()
    {
        $rule = new StrongPassword;

        $this->assertTrue($rule->passes('password', 'StrongPass1'));
        $this->assertFalse($rule->passes('password', 'weakpass'));
    }
}

Conclusion

Custom validation rules in Laravel provide a powerful way to encapsulate complex validation logic, improve code reusability, and enhance the overall structure of your application. By leveraging this feature, you can create more robust, maintainable, and testable validation processes in your Laravel projects. Whether you're dealing with complex business logic or simply want to keep your code DRY, custom validation rules are an invaluable tool in any Laravel developer's toolkit.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe