skip to Main Content

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


  1. Chosen as BEST ANSWER

    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.


  2. 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 using json_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:

    1. Use Laravel’s request directly:
      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.
    2. Fix the Validation Logic in the Controller:
      Update your controller method to work with Laravel’s Request object:
    public function yourMethod(Request $request)
    {
        // Use Laravel's automatic request data handling
        $validator = Validator::make($request->all(), [
            'name' => 'required|max:100',
            'price' => ['required', new FlexibalCurrencyRule],
        ]);
    
        if ($validator->fails()) {
            // Send the validation error response to the browser
            return response()->json($validator->errors(), 400);
        }
    
        // Continue with further logic if validation passes
    }
    
    1. est the Custom Rule:By using $request->all(), Laravel will automatically handle validation messages correctly and call the message() method on your custom rule.

    2. 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:

    public function yourMethod(Request $request)
    {
        $requestDto = json_decode($request->getContent(), true);
    
        $validator = Validator::make($requestDto, [
            'name' => 'required|max:100',
            'price' => ['required', new FlexibalCurrencyRule],
        ]);
    
        if ($validator->fails()) {
            return response()->json($validator->errors(), 400);
        }
    
        // Continue with further logic if validation passes
    }
    

    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 the message() method output.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search