Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON defualt value #16107

Closed
hafezd opened this issue Oct 26, 2016 · 4 comments
Closed

JSON defualt value #16107

hafezd opened this issue Oct 26, 2016 · 4 comments

Comments

@hafezd
Copy link

hafezd commented Oct 26, 2016

  • Laravel Version: 5.3.19
  • PHP Version: 7.0.8
  • Database Driver & Version: Mysql 5.7.15

Description:

I have documents table with parameters JSON column and a model like this:

class Document extends Model {

    /**
     * The attributes that should be casted to native types.
     *
     * @var array
     */
    protected $casts = [
        'parameters' => 'array',
    ];

}

JSON columns cannot have a default value in Mysql and no update will happen if the value of the column is NULL or empty, so according to this suggestion, I use stdClass when create.

But It doesn't make sense to set JSON column to stdClasss on every single insertion and there should be a way to give it a default value of empty object {}.

I tried to use this mutator to set default value when empty but no chance:

    /**
     * Set the parameters.
     *
     * @param  string  $value
     * @return string
     */
    public function setParametersAttribute($value)
    {
        $this->attributes['parameters'] = empty($value) ? new stdClass() : $this->asJson($value);
    }


SQLSTATE[HY000]: General error: 1364 Field 'parameters' doesn't have a default value

I think Eloquent Model should set an empty object for JSON column types during creation.

Steps To Reproduce:

  1. JSON column doesn't accept default value.
  2. Updating null JSON column is not possible.
@themsaid
Copy link
Member

themsaid commented Oct 26, 2016

This is a MySQL thing :) I guess there are many inconsistencies in the JSON type column, like the integer/float comparison that is type strict unlike the rest of the MySQL fields.

However if you have any suggested approaches to deal with the matter please feel free to open a PR.

@arctic-ice-cool
Copy link

arctic-ice-cool commented Nov 24, 2016

The workaround I'm going to use (reluctantly) is to add this to the Model with the JSON field:

protected $attributes = array(
        'json' => '{}'
    );

The downside to this is that this won't affect existing Model records already created and saved in the DB - so an additional query needs to be run as part of a migration or seed to fix this and update existing records.

#15433 - arctic-ice-cool commented

@ctrlaltdylan
Copy link

ctrlaltdylan commented Nov 15, 2018

Oh the joy of little hacks. Here's a simple accessor that solved the issue for me (like @hafezdivandari I too have a parameters attribute on my model):

    /**
     * Accessor for the options attribute.
     * Defaults to an empty array.
     */
    public function getParametersAttribute($value)  
    {
        if (empty($value)) {
            return [];
        }

        return json_decode($value, TRUE);
    }


    /**
      * Set that jawn on the way out
      */
    public function setParametersAttribute($value) {
        $this->attributes['parameters'] = json_encode($value);
    }

@dimer22zhc
Copy link

u can just do
protected $casts = ['json']; in your modal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants