This package allows validation and custom casts for JSON columns.
Have you ever tried to use a json column, and:
- Validating schema of the column was difficult or messy
- Querying the column was onerous
- Casting types when saving models wasn't fun
Well now you can rest easy!
You want to save user preferences. It's highly dynamic data, so you throw it into a json column:
Database Table | Database Column | Desired Schema |
---|---|---|
users | preferences |
[
{
"name": "Favorite Band",
"value": "Slenderbodies",
"date_created": "2019-09-15",
"date_updated": "2020-01-01"
}
] |
Here are problems:
- Can you enforce each key is valid?
- Can you enforce the two dates are valid dates?
- What about always ensuring the column is an array, regardless if a preference exists or not?
We can.
Let's use Laravel's own Validator syntax to describe what we want.
<?php
namespace App\Models\User;
use Zschuessler\ModelJsonAttributeGuard\JsonAttributeGuard;
class PreferencesJsonColumn extends JsonAttributeGuard
{
public function schema() : array
{
return [
// Use wildcard syntax to apply rules to all children
'*.name' => 'required',
'*.value' => 'required|min:3',
'*.date_created' => 'present|nullable|date',
'*.date_updated' => 'present|nullable|date',
];
}
}
Under the hood Laravel's Validators are used: you can use any rule you want. Go nuts.
Let's tell Laravel we want our model to do a custom cast:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\User\PreferencesJsonColumn;
use Zschuessler\ModelJsonAttributeGuard\Traits\HasJsonAttributeGuards;
class User extends Model
{
use HasJsonAttributeGuards;
public $casts = [
'preferences' => PreferencesJsonColumn::class
];
This code will work wonderfully:
$user->preferences = [
[
'name' => 'Favorite Band',
'value' => 'Slenderbodies',
'date_created' => '2019-09-15',
'date_updated' => '2020-01-01'
]
];
$user->save();
Great! But the code below will throw a JsonAttributeValidationFailedException
exception - oh no! Your model won't be saved.
$user->preferences = [
'name' => null,
'value' => null,
'date_created' => null,
'date_updated' => null,
];
$user->save();
This was a simple example. The possibilities are endless!