4

My model is defined as follows:

<?php
namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Database\Schema\Table as Schema;

class AppLogsTable extends Table
{    
    protected function _initializeSchema(Schema $schema) {
        $schema->columnType('data', 'json');
        return $schema;
    }       
}

The JSON format is correctly applied when saving into database and when retrieving data. However, if I set $appLog->data = null and save it through $this->appLogs->save($appLog) it would save a string null into the database rather than a real NULL value. The colum data in the app_logs table is set to accept nulls.

If I uncomment the column type definition, it stores nulls correctly.

How to keep the automatic JSON data type and store NULL correctly from the model?

Liglo App
  • 3,719
  • 4
  • 30
  • 54

1 Answers1

3

You'll have to use a custom/extended database type class that handles null values accordingly, the built-in one will pass everything through json_encode() no matter what.

Something along the lines of this:

// src/Database/Type/NullAwareJsonType.php

namespace App\Database\Type;

use Cake\Database\Driver;
use Cake\Database\Type\JsonType;

class NullAwareJsonType extends JsonType
{
    public function toDatabase($value, Driver $driver)
    {
        if ($value === null) {
            return null;
        }

        return parent::toDatabase($value, $driver);
    }
}

You can then either override the built in json type:

// config/bootstrap.php

\Cake\Database\Type::map('json', \App\Database\Type\NullAwareJsonType::class);

or map it as a new type and set the column type accordingly:

\Cake\Database\Type::map('nullAwareJson', \App\Database\Type\NullAwareJsonType::class);
$schema->columnType('data', 'nullAwareJson');

See also

ndm
  • 59,784
  • 9
  • 71
  • 110
  • 1
    After seeing this (and experiencing this myself a few times) I think it might be time to pluginize this: See [Shim plugin PR](https://github.com/dereuromark/cakephp-shim/pull/10). – mark Oct 21 '17 at 21:03