I am using Laravel 8.75 and I want to validate fields. I have created a custom rule to validate money.
The rule looks like this:
<?php
namespace AppRules;
use IlluminateContractsValidationRule;
class FlexibalCurrencyRule implements Rule
{
private $regex = '/^([0-9]{1,10})([.,][0-9]{1,2})?$/';
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
return preg_match($this->regex, $value);
}
/**
* Get the validation error message.
*
* @return string | array
*/
public function message()
{
return "currency";
}
}
It is very plain and simple. Then in my controllers I do the following:
$requestDto = json_decode($request->getContent(), true);
$validator = Validator::make($requestDto, [
'name' => 'required|max:100',
'price' => ['required', new FlexibalCurrencyRule],
]);
if ($validator->fails()) {
// Send response to browser
}
When I call the endpoint my validation messages contain the following:
"price": {
"App\Rules\FlexibalCurrencyRule": []
}
As you can see Laravel doesn’t call the message() function. It just prints the class name. From what I understand it should call the message() function and return ‘currency’ as the validation rule. How can I convert a custom rule into a string message instead of the class name being returned?
2
Answers
I have found the answer. I was calling the failed() function on the validator object. This returns the wrong information. You need to call messages() on the validator object to get the actual messages.
The issue you’re encountering with Laravel printing the class name
App\Rules\FlexibalCurrencyRule
instead of the custom message is likely due to how you’re decoding the request content usingjson_decode
before running validation. Laravel expects the request data to come from its built-in request handling, not from manually decoded JSON.Here’s how you can address the problem:
Instead of manually decoding the request content using
json_decode
, allow Laravel to automatically handle the request, which ensures proper validation and error message handling.Update your controller method to work with Laravel’s
Request
object:est the Custom Rule:By using
$request->all()
, Laravel will automatically handle validation messages correctly and call themessage()
method on your custom rule.If you still need to decode JSON manually: If your request is still coming as raw JSON and you need to manually decode it, wrap the custom rule within the
json_decode
part carefully:Using Laravel’s built-in
$request->all()
will ensure proper handling of the validation rules and messages. This approach should solve the issue where the class name is returned instead of themessage()
method output.