Laravel 5.8 update mysql json column cast as array changes data stored format

你离开我真会死。 提交于 2019-12-13 03:58:28

问题


I have a table with a json column cast as array. The Schema creation has the column defined like this:

$table->json('row_ids');

In my class:

protected $casts = [
    'row_ids' => 'array',
];

I generate the data in this array / column by getting every row id from another table like this:

$id_array = DB::table($table->name)->pluck('api_id')->toArray();

TableChannelRow::create([
    'table_api_id' => $table->api_id,
    'channel_api_id' => $channel->api_id,
    'row_ids' => $id_array,
]);

When I dd a collection record I can see the columns in the target table OK, with one of the columns containing an array as expected:

#attributes: array:4 [▼
  "api_id" => 2
  "table_api_id" => 1
  "channel_api_id" => 6
  "row_ids" => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,  ▶"
]

When I check in MySQLWorkbench the data looks like this:

In another controller I want to add or remove entries from the array in this column like this:

$table_channel_row = TableChannelRow::where('table_api_id', '=', $rowId)
    ->where('channel_api_id', '=', $channelId)
    ->first();

$row_ids = $table_channel_row->row_ids;

if ($is_checked == 'yes') {

    // Add value to array if it does not already exist
    if (!in_array($row_id, $row_ids)) {
        array_push($row_ids, $row_id);
    }

} else {

    // Remove value from array
    $row_id_array[] = $row_id;
    $row_ids = array_diff($row_ids, $row_id_array);

}

$table_channel_row->update([
    'row_ids' => $row_ids,
]);

Now the data in MySQLWorkbench looks like this:

Why does it get stored looking like a PHP array in the first instance, then later on update it gets stored as a json object?

Additionally the remove PHP code is working, yet the add is not, though it does not trigger an exception (you can see the first value is removed in the second image, but I cannot find it in the object in MySQL when I trigger the code to add it)

What did I miss? Thanks!


回答1:


The reason why it's saving differently is because array_diff returns an associative array whereas your initial data is an indexed array. Take the following for example:

$ids = [1, 2, 3, 4, 5];
$ids2 = [1, 2, 3];

Then if you perform an array_diff($ids, $ids2), it would return the following:

[
    3 => 4,
    4 => 5
]

So if you want to save as the same format as your initial one, you have to retrieve the values of the array using array_values:

$row_ids = array_values(array_diff($row_ids, $row_id_array));


来源:https://stackoverflow.com/questions/55729084/laravel-5-8-update-mysql-json-column-cast-as-array-changes-data-stored-format

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!