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?
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