Quick Note: Default Value for JSON in Laravel
Many RDBMS today have json
data type implemented. MySQL has it since 5.7.8 and PostgreSQL since 9.3. MariaDB, a MySQL-like RDBMS solution, has json
as an alias to longtext
, that means while MySQL and PostgreSQL can search and validate JSON data, MariaDB does not.
Laravel also supports JSON columns since 5.x. They do not, however, sometimes work as you expect it to be. I ran across a problem about setting a default value for a JSON column and, in this article, I would like to present you how I've solved the issue.
How to Do It
After starting a new Laravel project with laravel new whatever
, we need to create an example model with its migrations that we can work on.
php artisan make:model Article -m
This will both generate the model and migration file for us.
Then we write our migration as such:
$table->text("content"); // for the sake of example
$table->json("tags")->default("[]");
The column tags
here is a json
typed column but here is the catch: It might not work (tested in PostgreSQL). In such cases, you can use a pre-create (creating) hook to set the default value before saving. To do that, we need to open up our model, app/Article.php
in this case, and override built-in static booted
method of the model:
protected static function booted() {
// when the model is loaded
}
Here we can define any event in lifetime of our model. You can see a list here. In our case, we need to define a creating
event as such:
protected static function booted() {
static::creating(function ($article) {
if ($article->tags === null) {
// if tags are not provided on creation
$article->tags = "[]"; // set empty json array
}
});
}
Note that we actually check if tags
property is null
. We need it to be set to empty JSON array only in case we have not provided values by hand on creation.
Also another note is that, on creating
event, we do not call any save
method or something alike (which is querying the database). It's because we are literally injecting a value to $article
instance, which is not yet saved. Laravel will save it after creating
event runs.
After this, it will set default value to empty JSON array in database. Thanks for reading.