Skip to content
DanSmith83 edited this page Jun 12, 2015 · 2 revisions

Validable

Validable is the one to grant your model super-cow powers :)

All you need to do is to define the rules, everything else will be done for you:

  • validation on creating with provided rules.
  • validation on updating with auto-adjusted rules for update (unique checks).
  • auto-validation can be skipped for next saving attempt or disabled completely for given instance.
  • rules can be defined as one or many properties for your convenience - see the example.
  • additionally you will never have to worry about incorrect attributes set on your model (incorrect in that they are not referring to actual columns on the table, so would cause DB error) - they will be cleaned on saving, thanks to the Eloquence base trait, just implement CleansAttributes contract.
<?php namespace App;

use Sofa\Eloquence\Eloquence; // base trait
use Sofa\Eloquence\Validable; // extension trait
use Sofa\Eloquence\Contracts\CleansAttributes;
use Sofa\Eloquence\Contracts\Validable as ValidableContract;

class User extends \Eloquent implements ValidableContract, CleansAttributes {

  use Eloquence, Validable;

  // You may use $rules and/or any number of $someRules, $otherRules etc
  // properties for your convenience - they will be all merged together.
  // 
  // Available rules as described in the laravel docs:
  // @link http://laravel.com/docs/5.0/validation#available-validation-rules
  protected static $businessRules = [
    'name'  => 'required|min:5', // rules passed as pipe-separated string
    'email' => ['required', 'email', 'unique:users'] // or as an array
  ];

  protected static $dataIntegrityRules = [
    'email' => 'max:255',
  ];

  // You can also pass custom attribute names and validation messages
  // just like when using Laravel Validator directly.
  protected static $validationAttributes = [
    'email' => 'EMAIL',
    'name'  => 'REAL NAME',
  ];

  protected static $validationMessages = [
    'required'       => 'Man, field :attribute must be filled!',
    'email.required' => 'Man, gimme your email?!',
  ];

}

Example usage:

>>> User::getCreateRules()
// [
//     "email" => [
//         "required",
//         "email",
//         "unique:users",
//         "max:255"
//     ],
//     "name"  => [
//         "required",
//         "min:5",
//     ]
// ]
>>> User::getUpdateRulesForId(10)
// [
//     "email" => [
//         "required",
//         "email",
//         "unique:users,name,10,id",
//         "max:255"
//     ],
//     "name"  => [
//         "required",
//         "min:5",
//     ]
// ]
>>> User::getValidatedFields()
// [
//     "email",
//     "name"
// ]

>>> $user = new User
// <App\User #0000000018ab2ca40000000013cb0d59> {}

>>> $user->isValid()
// false

>>> $user->getValidationErrors()
// <Illuminate\Support\MessageBag #0000000018ab2c8d0000000013cb0d59> {}

>>> $user->getValidationErrors()->all()
// [
//   "Man, gimme your email?!",
//   "Man, field REAL NAME must be filled!"
// ]

>>> $user->email = 'invalid'
// "invalid"
>>> $user->name = 'foo'
// "foo"
>>> $user->save()
// false
>>> $user->getValidationErrors()->all()
// [
//   "The EMAIL must be a valid email address.",
//   "The REAL NAME must be at least 5 characters."
// ]

>>> $user->skipValidation()->save()
// true

>>> $user->getUpdateRules()
// [
//     "email" => [
//         "required",
//         "email",
//         "unique:users,name,224,id",
//         "max:255"
//     ],
//     "name"  => [
//         "required",
//         "min:5",
//     ]
// ]

Easy integration with form requests

Chances are, you are using Form Requests extensively in your Laravel web app. That said, you might be afraid of the duplication of the rules in both model and corresponding form request, but worry no more.

Here's how easily you can integrate your validable model and form request:

<?php namespace App\Http\Requests;

use App\Http\Requests\Request;
use App\User;

class UpdateUserRequest extends Request {

  public function authorize()
  {
    return true;
  }

  // get the rules
  public function rules()
  {
    $id = $this->users; // assuming resource controller and {users} uri param

    return User::getUpdateRulesForId($id);
  }

  // CreateUserRequest would be simply returning rules as defined in the model
  // public function rules()
  // {
  //   return User::getCreateRules();
  // }

  // pass custom messages if defined
  public function messages()
  {
    return User::getValidationMessages();
  }

  // and attributes as well
  public function attributes()
  {
    return User::getValidationAttributes();
  }
}

Less boilerplate thanks to Eloquence Model

Most likely you will want to use auto validation on all your models, so instead of adding the traits and contracts manually, simply extend Sofa\Eloquence\Model. It provides Validable and CleansAttributes contracts implementation for you.

Clone this wiki locally