OminousMusic
OminousMusic

Reputation: 69

Laravel 8 Save JSON manually in Database

When I save a product to my Database column images everything in the JSON column is filled correctly:

[
    {
        "path": "/uploads/n2R9y4l977/20210104_125201.jpg",
        "index": "0"
    },
    {
        "path": "/uploads/n2R9y4l977/20201222_144730.jpg",
        "index": "1"
    }
]

So what I try to do next, is to delete a row in this column by checking if the given data matches the index. So I do the following:

    $newImage = [];
    $product = product::where(["id" => $product_id])->first();
    //$product = product::find($product_id); gives the same result

    $originalProduct = $product->images;

    foreach($originalProduct as $key => $images) {
        if ($images->index == $index) {
            unset($originalProduct[$key]);
        }
    }

    foreach($originalProduct as $key => $image) {
        $newImage[$key] = array("index" => "".$key, "path" => $image->path);
    }

    $product->images = $newImage;
    $product->save(); //also tried $product->update();

Which gives me this:

{
    "1": {
        "path": "/uploads/n2R9y4l977/20201222_144730.jpg",
        "index": "1"
    }
}

Product model has a cast:

protected $casts = [
        'images' => 'object',
    ];

But I need it to be exactly like the first time I saved this to the DB. How do I do this?

Upvotes: 0

Views: 596

Answers (2)

OminousMusic
OminousMusic

Reputation: 69

This seems to fix it:

Between the 2 foreaches I added an array_values()

foreach($originalProduct as $key => $images) {
   if ($images["index"] == $index) {
         unlink($originalProduct[$index]["path"]);
         unset($originalProduct[$index]);
   }
}

$originalProduct = array_values($originalProduct);

foreach($originalProduct as $key => $image) {
   $newImage[$key] = array("index" => "".$key, "path" => $image["path"]);
}

$product["images"] = $newImage;
$product->save();

Before these changes, the array would be like: [1 => '', 2 => '', 4 => '', 7 => '']

I also changed the cast of my model from Object to Array

protected $casts = [
    ‘images’ => ‘array’
];

Because the reindex of the array happens with array_values() it now seems to always return the expected JSON object.

Upvotes: 0

Rory
Rory

Reputation: 2496

You can use the following to get the json without the cast:

$originalProduct = $product->getRawOriginal(‘images’);

Alternatively you could change the cast to array if this won’t break functionality for you elsewhere:

protected $casts = [
    ‘images’ => ‘array’
];

Upvotes: 1

Related Questions