# Write Your Laravel Validation Logic Like a Senior Dev, Part 2

Sometimes the rules that come pre-built into Laravel are not enough. Luckily, Laravel provides a way for you to create your own rules using a separate Rule class. In this post, I'll show you how we can create a custom rule that makes sure passwords are at least 8 characters and includes a symbol, a number, and a lower and upper case letter.

**Preliminaries:**
- Go back to the [previous post](https://blog.lloydmiller.dev/write-your-laravel-validation-logic-like-a-senior-dev-part-1) to see how you should set up your project.
    * This rule will only be used for ***RegisterRequest***, so focus on making sure that's set up properly.
- If you haven't already, [download and install Postman](https://www.postman.com/downloads/).
- Don't forget to run your server! `php artisan serve`

**The Work Begins:**
- We'll create our custom rule by running `php artisan make:rule StrongPassword`. 
    * You can find your new rule in ***app/Http/Rules/StrongPassword.php***.  
    * In your custom rule you will see a constructor and two methods: `passes()` and `message()`. The `passes()` method will check to see if the `$attribute`'s condition in terms of the `$value` is met and returns either true or false. The `message()` method returns whatever string you want to return when `passes()` is false.
- The best way to ensure that a string follows a certain pattern is to use regular expressions. In PHP, we use the function `preg_match()` to help with that.

**The Work Continues:**
- I'm not a god at regex but luckily I found one that works. Here's how we'll pattern match the `$attribute`'s `$value` to return a boolean:

```
public function passes($attribute, $value)
    {
        return preg_match("/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@()$%^&*=_{}[\]:;\"'|\\<>,.\/~`±§+-]).{8,30}$/", $value);
    }
```
- So if it doesn't pass (returns false), our defined error message will be returned. 

```
public function message()
    {
        return 'Your :attribute must be at least 8 characters and must include a number, a symbol, a lower and an upper case letter';
    }
```
- **NB:** Since `password` is the attribute that we're making a rule for, it will replace `:attribute` in our string.

**The Work Ends:**
- Go into ***RegisterRequest*** and import `StrongPassword`. Now we need to instantiate it so we can use it. We'll replace the value for `password` in our `rules()` method and use an array instead.

```
use App\Rules\StrongPassword;
...

public function rules()
{
    return [
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => ['required', 'string', new StrongPassword],
    ]
}
```
- Now when we run it we should see something like this:

![Screenshot 2021-03-10 152711.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1615408066839/cyr_gRNUa.jpeg)

**Conclusion:**
- Having custom rules gives you a lot more options. You can add a lot more logic for even more robust rules. In a future post, I'll show you how I used a trait to make datetime-based custom rules.
- In our next post we'll be discussing After Validation Hooks.


%%[buyme]

