Framework: Saving to casted json column will store an escaped json string

Created on 18 Jul 2017  路  15Comments  路  Source: laravel/framework

  • Laravel Version: 5.4.28
  • PHP Version: 7.1.1
  • Database Driver & Version: MySQL 5.7.11

Description:

Saving model with json column will save an escaped json if cast. Am I missing something here? Is this intentional?

If not cast,
[{"code": "a", "name": "a"}, {"code": "b", "name": "b"}, {"code": "c", "name": "c"}]

If cast,
"[{\"name\":\"a\",\"code\":\"a\"},{\"name\":\"b\",\"code\":\"b\"},{\"name\":\"c\",\"code\":\"c\"}]"

Steps To Reproduce:

Add to model

    protected $casts = ['tags' => 'array'];

Then save the model

Most helpful comment

Looks like something in your code is already serializing the attribute so when Eloquent serializes it again it appears like this, check your code as the current settings work just fine.

All 15 comments

Looks like something in your code is already serializing the attribute so when Eloquent serializes it again it appears like this, check your code as the current settings work just fine.

Thanks, I tried something just now and now I get what the cast attribute is really doing.

@adifaidz How do you fix it? still use model cast or not?

@adifaidz When you store to DB, You should store in array format not json_encode().

@ThunderBirdsX3 If I do like that. I will get mysql error "Array to string conversion", Because I use model cast. It save array as json automically.

@ALTELMA Look like your database version not support. Or your column not JSON type.

My database support column json type. I can store directly, but cannot save from Laravel.

Bad Example:
Insert into users ('name', 'meta') VALUES ('ALTELMA', {"facebook":"","google":"","linked":""})

Should be:
Insert into users ('name', 'meta') VALUES ('ALTELMA', '{"facebook":"","google":"","linked":""}')

I don't know why laravel save value without quote.

Show your Model and code.

Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'meta' => 'array',
    ];

Save

$user = new User;
foreach($inputs as $key => $value) {
    $user->{$key} = $value;
}

$user->save();

@ALTELMA User::create(['name' => $inputs->name, 'meta' => $inputs->meta]);
I'm not sure, What is your $inputs it's $request?

Yes, it's $request, but why I cannot use save()?

@ALTELMA What is your data in meta look like? dd($request->meta);

Data store in array format like this.
["facebook":"123", "twitter":"456"]

Actually that's example data. Main point is when save data should be "{}" not {}.

I think I have problem only save() function.

Thanks Mohamed (@themsaid)

@adifaidz When you store to DB, You should store in array format not json_encode().

This comment alone has saved my day. I had the same issue - casting JSON column and spent ~2 hours last night trying to fix it and couldn't. Following the advice helped me resolve it.

Thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mstnorris picture mstnorris  路  87Comments

PheRum picture PheRum  路  112Comments

robjbrain picture robjbrain  路  64Comments

sebastianbergmann picture sebastianbergmann  路  93Comments

rafaelrenanpacheco picture rafaelrenanpacheco  路  64Comments