Super quick tip today, while I attempt to find some time to write a longer article on JSON columns in Laravel.

If you are declaring fillable attributes in a Laravel model that utilizes JSON columns, you will have to declare each array key individually.

class Something extends Model
{
    /**
     * @var array
     */

    protected $casts = [
        'phone_numbers' => 'json',
        ...
    ];
    
    /**
     * @var array
     */
    protected $fillable = [
        'phone_numbers',
        ...
    ];

The above example needs to have each key for the phone_numbers column explicitly declared using the arrow accessor to support mass assignment:

    protected $fillable = [
        'phone_numbers->mobile',
        'phone_numbers->office',
    ];

Of course, you can always just declare the inverse with the $guarded property instead:

    protected $guarded = [
        'email', 
        ...
    ];