dwightwatson / validating

Automatically validating Eloquent models for Laravel
MIT License
968 stars 76 forks source link

Validates correctly but Messagebag always empty. #194

Closed curtd59 closed 6 years ago

curtd59 commented 6 years ago

First, I absolutely love this package. It's 'done right'. Thanks for sharing your work.

I'm having an odd problem I assume is my fault, but after $myUser->isvalid(), or $myUser->save(), $myUser->getErrors() always returns an empty messagebag.

BASE MODEL

use Illuminate\Database\Eloquent\Model;
use Watson\Validating\ValidatingTrait;

abstract class BaseModel extends Model{
    use ValidatingTrait; 
   ...
  // (Defaults for all fields required by ValidatingTrait specified)

MODEL EXCERPT

class SysUser extends BaseModel  { ...
...
    protected $rules = [
        'user_home_server_id' => 'required|integer',
        'first_name' => 'required|min:2|max:40|alpha_space',
        'last_name' => 'required|min:2|max:80|alpha_space',
        'gender' => 'required|in:M,F',
        'email' => 'required|email',
        'state' => 'required|in:100,200,300,400,500',
    ];

    protected $validationMessages = [
        'user_home_server_id' => 'A Home Server ID is required for .....',
        'first_name'  => 'First Names are required, and must be at least two, and ... ',
        'last_name'  => 'Last Names are required, and ... ',
        'gender.in' => 'Sorry, but Gender is required, and ...',
        'gender.required' => 'Sorry, but Gender is required, and ...',
        'password' => 'A password is required and ...',
        'state' => 'A user status is required, and must ....',
    ];

TERMINAL TEST:

>>> $u = SysUser::findOrFail(4);

=> App\SysUser {#1091
     user_home_server_id: 1,
     sys_user_id: 4,
     first_name: "John",
     last_name: "Doe",
     gender: "M",
     email: "joe.abc@xyz.com",
     remember_token: null,
     created_at: "2017-12-19 21:16:34",
     updated_at: "2017-12-23 20:13:15",
     state: 100,
   }
>>> $u->save()
=> true
>>> $u->gender = 'X';  // enter an invalid value.
=> "X"
>>> $u->isvalid()
=> false
>>> $u->save()
=> false
>>> $u->getErrors()
=> Illuminate\Support\MessageBag {#1082}

No matter what I do I can't get something from getErrors.

Thanks for any help.

VERSIONS PHP 7.1.8 (cli) (built: Aug 17 2017 11:34:56) ( NTS ) Laravel Installer version 1.5.0 Laravel Framework 5.5.27

{ "name": "laravel/laravel", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "type": "project", "require": { "php": ">=7.0.0", "barryvdh/laravel-ide-helper": "^2.4", "doctrine/dbal": "^2.6", "fideloper/proxy": "~3.3", "florianv/laravel-swap": "^1.1", "jlapp/swaggervel": "dev-master", "laracademy/generators": "^1.3", "laravel/framework": "5.5.*", "laravel/horizon": "^1.0", "laravel/passport": "^4.0", "laravel/tinker": "~1.0", "laravelcollective/html": "^5.5.0", "nesbot/carbon": "^1.22", "orangehill/iseed": "^2.5", "php-http/guzzle6-adapter": "^1.1", "php-http/message": "^1.6", "predis/predis": "^1.1", "waavi/translation": "2.3.x", "watson/validating": "^3.1" }, "require-dev": { "filp/whoops": "~2.0", "fzaninotto/faker": "~1.4", "krlove/eloquent-model-generator": "^1.2", "mockery/mockery": "~1.0", "phpunit/phpunit": "~6.0", "xethron/migrations-generator": "^2.0" }, "autoload": { "classmap": [ "database/seeds", "database/factories" ], "psr-4": { "App\": "app/" } }, "autoload-dev": { "psr-4": { "Tests\": "tests/" } }, "extra": { "laravel": { "dont-discover": [ ] } }, "scripts": { "post-root-package-install": [ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" ], "post-create-project-cmd": [ "@php artisan key:generate" ], "post-autoload-dump": [ "Illuminate\Foundation\ComposerScripts::postAutoloadDump", "@php artisan package:discover" ] }, "config": { "preferred-install": "dist", "sort-packages": true, "optimize-autoloader": true } }

dwightwatson commented 6 years ago

I just created a fresh project and tried to recreate what you're doing. However - I had to remove the validation rules for alpha_space as I didn't have them, I assume they're custom validations of yours.

{
  "gender": [
    "Sorry, but Gender is required, and ..."
  ]
}

When making the same change to gender of X I got the expected validation. Not sure what's going on here for you but maybe as a sanity check could you remove the use of alpha_space and try again, see if the package works as you expect then? It would help narrow down where things are going wrong.

curtd59 commented 6 years ago

Thanks so much for the quick response.

Cleaned existing install. Tried new install. Same problem both times.

EXISTING INSTALL I did remove the custom validations, removed the references, updated composer, executed dump-autoload

This project is fresh other than generating the models from the db tables. I've removed "waavi/translation": "2.3.x", "florianv/laravel-swap": "^1.1", "jlapp/swaggervel": "dev-master", which leaves me with a base install. (I think).

NEXT TRIED A FRESH INSTALL moved over model, env settings, db config settings. Still the same issue. (I'm dumbfounded)

ONE FILE:


namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Watson\Validating\ValidatingTrait;

class SysUser extends Model   {

    // protected $throwValidationExceptions = true;
    use ValidatingTrait;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'sys_user';
    protected $primaryKey = 'sys_user_id';

    /**
     * Attributes that should be mass-assignable.
     *
     * @var array
     */
    protected $fillable = [
        'first_name',
        'last_name',
        'gender',
        'email',
        'remember_token',
        'state',
        'last_login'
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    // protected $hidden = ['password'];

    /**
     * The attributes that should be casted to native types.
     *
     * @var array
     */
    protected $casts = [
        'first_name' => 'string',
        'last_name' => 'string',
        'gender' => 'string',
        'email' => 'string',
        'password' => 'string',
        'state' => 'integer',
        'remember_token' => 'string'
    ];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = [
        'created_at',
        'updated_at',
        'last_login',
    ];

    /**
     * Validation rules
     *
     * @var array
     */
    protected $rules = [
        'user_home_server_id' => 'required|integer',
        'first_name' => 'required|min:2|max:40',
        'last_name' => 'required|min:2|max:80',
        'gender' => 'required|in:M,F',
        'email' => 'required|email',
        'state' => 'required|in:100,200,300,400,500',
    ];

    protected $validationMessages = [
        'user_home_server_id' => 'A Home Server ID is required for every User. You should not see this message unless something is seriously wrong.',
        'first_name'  => 'First Names are required, and must be at least two, and no more than forty characters, and use only letters and spaces.',
        'last_name'  => 'Last Names are required, and must be at least two, and no more than eighty characters, and use only letters and spaces.',
        'gender.in' => 'Sorry, but Gender is required, and must be (M)ale or (F)emale. Human chromosomes only come in XY or XX.',
        'gender' => 'Sorry, but Gender is required, and must be (M)ale or (F)emale. Human chromosomes only come in XY or XX.',
        'password' => 'A password is required and must consist of six or more characters, at leaset one capital, at least one digit, and at least one special character.',
        'state' => 'A user status is required, and must exist in the list of available statuses.',

    ];
}

TERMINAL:

CurtD15R-2014:freshrun curtd$ php artisan tinker
Psy Shell v0.8.16 (PHP 7.1.8 — cli) by Justin Hileman
>>>  $u = App\Models\SysUser::findOrFail(4);
=> App\Models\SysUser {#747
     user_home_server_id: 1,
     sys_user_id: 4,
     first_name: "Christian",
     last_name: "Danelaw",
     gender: "M",
     email: "chris.danelaw@gmail.com",
     password: "Proposal!59",
     remember_token: null,
     created_at: "2017-12-19 21:16:34",
     updated_at: "2017-12-23 20:13:15",
     state: 100,
     last_login: null,
   }
>>> $u->gender = 'Z'
=> "Z"
>>> $u->save()
=> false
>>> $u->getErrors()
=> Illuminate\Support\MessageBag {#735}
>>> $u
=> App\Models\SysUser {#747
     user_home_server_id: 1,
     sys_user_id: 4,
     first_name: "Christian",
     last_name: "Danelaw",
     gender: "Z",
     email: "chris.danelaw@gmail.com",
     password: "Proposal!59",
     remember_token: null,
     created_at: "2017-12-19 21:16:34",
     updated_at: "2017-12-23 20:13:15",
     state: 100,
     last_login: null,
   }
>>> e$ = $u->getErrors()
PHP Parse error: Syntax error, unexpected '$' on line 1
>>> $e = $u->getErrors()
=> Illuminate\Support\MessageBag {#735}
>>> 
dwightwatson commented 6 years ago

I just tried again using the terminal this time (I was using a web route before) and go the some output as you. The MessageBag is returned but the console simply doesn't show the errors that it contains. But if you actually start to use the MessageBag or cast it to a string I can see that it contains the errors as I expect...

>>> $sysUser->getErrors();
=> Illuminate\Support\MessageBag {#739}
>>> (string) $sysUser->getErrors()
=> "{"gender":["Sorry, but Gender is required, and ..."]}"
>>> $sysUser->getErrors()->first()
=> "Sorry, but Gender is required, and ..."
curtd59 commented 6 years ago

Interesting. Thank you very much. It is correct in your code. So it had to be something odd. Test cases just need the cast. Again. THANKS. /**

OUTPUTS:

$u->save() {"gender":["Sorry, but Gender is required, and must be (M)ale or (F)emale. Human chromosomes only come in XY or XX."]}⏎ => false