laravel-validator icon indicating copy to clipboard operation
laravel-validator copied to clipboard

Custom validation message not coming

Open ajeeshcitrus opened this issue 10 years ago • 7 comments

I am using repository pattern using L5-repository validation. This is my

controller

<?php

namespace App\Api\V1\Controllers;

use Request;
use Dingo;
use App\Http\Controllers\Controller;
use App\Repositories\UserRepository;
use App\Api\V1\Transformers\BankAccountTransformer;
use Prettus\Validator\Exceptions\ValidatorException;
use \Prettus\Validator\Contracts\ValidatorInterface;
use App\Api\V1\Validations\BankAccountValidator;

   public function store()
    {
        $request = Request::all();
        try {
                //Validate request body
                $this->validator->with(  $request )->passesOrFail(ValidatorInterface::RULE_CREATE);

        }  catch (ValidatorException $e) {
                throw new Dingo\Api\Exception\StoreResourceFailedException('Unable to add bank account', $e->getMessageBag()); 
  //  Wiki of the project says to use getMessage(), but it throws error

        }
    }

Validation class

<?php

    namespace App\Api\V1\Validations;

    use \Prettus\Validator\Contracts\ValidatorInterface;
    use \Prettus\Validator\LaravelValidator;

    class BankAccountValidator extends LaravelValidator {

        protected $rules = [
            ValidatorInterface::RULE_CREATE => [
            'bank_name' => 'required'
            ],
            ValidatorInterface::RULE_UPDATE => [
            ]
        ];

        protected $messages = [
            'bank_name.required' => 'My custom error'
        ];

    }

But I am getting this error when I use $e->getMessage() .

  "message": "Call to a member function isEmpty() on string"

If I am using $e->getMessageBag() I am getting proper error response. But my custom messages are not displayed. A generic message is displayed.

"errors": {
    "bank_name": [
      "The bank name field is required."
    ]
  }

It actually should have been

"errors": {
    "bank_name": [
      "My customer error"
    ]
  }

dd($e)

ValidatorException {#505
  #messageBag: MessageBag {#507
    #messages: array:1 [
      "bank_name" => array:1 [
        0 => "The bank name field is required."
      ]
    ]
    #format: ":message"
  }
  #message: ""
  #code: 0
  #file: "/home/vagrant/dev-develop/vendor/prettus/laravel-validation/src/Prettus/Validator/AbstractValidator.php"
  #line: 109
  -trace: array:58 [
    0 => array:3 [
      "call" => "Prettus\Validator\AbstractValidator->passesOrFail()"
      "file" => "/home/vagrant/dev-develop/app/Api/V1/Controllers/BankAccountController.php:61"
      "args" => array:1 [
        0 => "create"
      ]
    ]

ajeeshcitrus avatar Dec 24 '15 06:12 ajeeshcitrus

Having the same problem here

thecodecafe avatar Jan 24 '16 15:01 thecodecafe

Hi guys! I'm having the same problem here, but I know how to solve. Below, you can see a short tutorial:

  • On Prettus\Validator\AbstractValidator, I've created the function:

public function getMessages() { return $this->messages; }

  • On Prettus\Validator\LaravelValidator, I've updated the line 37 (inside public function passes):

$validator = $this->validator->make($this->data, $rules, $this->getMessages());

I don't know if its the right way to solve this problem, but at least now its working well for me!

lucashccosta avatar Feb 11 '16 16:02 lucashccosta

This issue is in release 1.1.4 which the readme instructions say to include in your composer file. If you change your composer to install dev-master like this "prettus/laravel-validation": "dev-master" then you'll get the most recent code with the fixes to get messages and attributes working.

ghost avatar Feb 17 '16 20:02 ghost

I've already installed "prettus/laravel-validation": "dev-master", but the issue still not solved. I think it 's because I didn't regenerate my entity. I found there may be a typo in the catch part from generator:

catch (ValidatorException $e) {

            if ($request->wantsJson()) {

                return response()->json([
                    'error'   => true,
                    'message' => $e->getMessage()  // HERE is THE PROBLEM
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }

'message' => $e->getMessage() should be 'message' => $e->getMessageBag(), I changed it and it works fine.

dj1020 avatar Apr 25 '16 07:04 dj1020

Having the same problem here

motamonteiro avatar Jul 05 '16 19:07 motamonteiro

I've installed "prettus/laravel-validation": "dev-develop as 1.1.4" and worked fine.

motamonteiro avatar Jul 07 '16 17:07 motamonteiro

@LucasCCosta Nice approach!

However, following SOLID rules, we cannot change AbstractValidator and LaravelValidator.

In this case I recommend ( and was my solution ) , create a class that extends LaravelValidator and containing these changes.

My suggestion:

  • create a "generic" Validator class
  • insert :
    • protected $messages;
    • public function getMessages() { return $this->messages; }
  • and overide passes function with your modification ;)
<?php

namespace App\Support\Validators;

use Illuminate\Validation\Factory;
use Prettus\Validator\LaravelValidator;

class Validator extends LaravelValidator
{
    protected $messages = array();

    public function getMessages() { return $this->messages; }

    /**
     * Pass the data and the rules to the validator
     *
     * @param string $action
     * @return bool
     */
    public function passes($action = null)
    {
        $rules     = $this->getRules($action);
        $messages  = $this->getMessages();
        $validator = $this->validator->make($this->data, $rules, $messages);

        if( $validator->fails() )
        {
            $this->errors = $validator->messages();
            return false;
        }

        return true;
    }
}

Cya!

jjcodes78 avatar Jul 28 '16 18:07 jjcodes78