DEV Community

loading...

Laravel validation rule — decimal

mattkingshott profile image Matt Kingshott 👨🏻‍💻 Originally published at Medium on ・3 min read

Image courtesy of Unsplash

Laravel validation rule — decimals

In this new series, we’ll be exploring the concept of custom validation rules in Laravel and how they can assist you. I’m posting an article each day with a new rule you can use in your projects. The rules are also part of a package.

In this post, we’ll be creating a rule which confirms that a user has supplied a decimal value of a given length and scale e.g. 1234.56.

If you’re new to this topic, check out the first article in the series.

Promotion

I’ve recently released Pulse — a friendly, affordable server and site monitoring service designed specifically for developers. It includes all the usual hardware monitors, custom service monitors, alerting via various notification channels, logs, as well as full API support. Take a look… https://pulse.alphametric.co

Server and Site Monitoring with Pulse

The check and response

Let’s begin by writing the logic necessary to ensure that the user has supplied a valid decimal. To do so, our rule will need to accept a length parameter and a scale parameter. We can then insert these parameters into a regular expression which forms the basis of the passes method:

public function passes($attribute, $value)
{
    return preg\_match("/^[0-9]{1,{$this->parameters[0]}}(\.[0-9]{1,{$this->parameters[1]}})$/", $value);
}
Enter fullscreen mode Exit fullscreen mode

The expression allows a user to give any number of digits before the point up to the supplied length parameter. Likewise, the expression allows a user to give any number of digits after the point up to the supplied scale parameter.

So, for example, new Decimal(4, 2) would allow a user to provide values such as 12.0, 123.4 and 1234.56 but not 1234.567 or 12345.67.

Next, we’ll need to write an error message to respond with when the user has supplied a decimal that does not meet the criteria. To aid them in fixing their mistake, we can also create an example method:

public function example()
{
    return mt\_rand(1, (int) str\_repeat('9', $this->parameters[0])) .
           '.' . 
           mt\_rand(1, (int) str\_repeat('9', $this->parameters[1]));
}


// ...


public function message()
{
    return 'The :attribute must be an appropriately formatted decimal e.g. ' . $this->example();
}
Enter fullscreen mode Exit fullscreen mode

Testing it works

As before, we’ll write a quick unit test to confirm that the rule works correctly and rejects values that are not suitably formatted:

/\*\* @test \*/
public function a\_decimal\_can\_be\_validated()
{
    $rule = ['figure' => [new Decimal(4, 2)]];

    $this->assertFalse(validator(['figure' => '1'], $rule)->passes());

    $this->assertFalse(validator(['figure' => '123'], $rule)->passes());

    $this->assertFalse(validator(['figure' => '1234'], $rule)->passes());

    $this->assertFalse(validator(['figure' => '1234.'], $rule)->passes());

    $this->assertTrue(validator(['figure' => '1234.5'], $rule)->passes());

    $this->assertTrue(validator(['figure' => '1234.56'], $rule)->passes());

    $this->assertFalse(validator(['figure' => '1234.567'], $rule)->passes());

    $this->assertTrue(validator(['figure' => '1234.0'], $rule)->passes());

    $this->assertTrue(validator(['figure' => '1234.00'], $rule)->passes());
}
Enter fullscreen mode Exit fullscreen mode

Wrapping Up

You can see the complete class and pull it into your projects by visiting the repo on Github: https://github.com/alphametric/laravel-validation-rules

I have additional validation rules that I intend to share with you in the coming days, so be sure to follow me for those articles. If you’re interested, you can also follow me on Twitter to see everything I’m up to.

Happy coding!

Discussion (0)

pic
Editor guide