Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migration - How to set default value for json? (MySQL)

Tags:

laravel

I have the problem that I need some values to be already set for my settings json column.

Let us say I have this in my user migration file:

$table->json('settings');

My goal is to set let us say these values as default:

'settings' => json_encode([
    'mail' => [
        'hasNewsletter' => false
    ],
    'time' => [
        'timezone' => ''
    ]
])

How would you do this?

My first approach was to set the values in my UserObserver in the created event after the User was created.

This creates the problem, that my UserFactory is not working correctly. Because a User is created but the settings values are overwritten by the UserObserver again...

like image 572
Philipp Mochine Avatar asked Sep 17 '25 02:09

Philipp Mochine


1 Answers

Following solution works with Eloquent Model.

For default JSON data you can do something like this in your Model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   
protected $attributes = [
        'settings' => '{
            "mail": {
            "hasNewsletter" : false
            },
            "time": {
            "timezone" : ""
            }
        }'
    ];
}

Then the default value will be {"mail": {"hasNewsletter" : false},"time": {"timezone" :""} in your DB if your input is null. However the existing values in DB will be unchanged and will have to change manually if you need.

If you want to keep your existing DB values null (and/or when null) but want to get as the above default json by Eloquent, you can add the following method in the Model:

    protected function castAttribute($key, $value)
    {
        if ($this->getCastType($key) == 'array' && is_null($value)) {
            return '{
                    "mail":{
                        "hasNewsletter":false
                            },
                    "time":{
                         "timezone":""
                           }
                     }';
        }
        return parent::castAttribute($key, $value);
    }

Note: above castAttribute method will return this same json/data for all null json column of your model. It's better to set empty array here.

Tested in Laravel 5.8. Reference: https://laravel.com/docs/eloquent#default-attribute-values

like image 162
Jaber Al Nahian Avatar answered Sep 18 '25 17:09

Jaber Al Nahian