Search code examples
phplaravel

laravel, How to update array in json column?


in my Laravel app, the database has a column named "mavads" as :

{
  "en": [
    {
      "need": "enn1",
      "amount": "enm1"
    },
    {
      "need": "enn2",
      "amount": "enm2"
    },
    {
      "need": "enn3",
      "amount": "enm3"
    },
  ],
  "ru": [
    {
      "need": "run1",
      "amount": "rum1"
    },
    {
      "need": "run2",
      "amount": "rum1"
    },
  ]
}

This is the form that send data as PUT to the controller to update the database:


@foreach($food->mavads['en'] as $m)
      <input type="text" class="input" name="enneed[]" value="{{ $m['need'] }}">
      <input type="text" class="input" name="enamount[]" value="{{ $m['amount'] }}">
@endforeach

@foreach($food->mavads['ru'] as $m)
      <input type="text" class="input" name="runeed[]" value="{{ $m['need'] }}">
      <input type="text" class="input" name="ruamount[]" value="{{ $m['amount'] }}">
@endforeach

the Food Model:

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

in Controller, I get $request and want to update each { "need": "run2","amount": "rum1"} of en or ru languages:

    $enmavad = $request->only('enneed', 'enamount');
    $rumavad = $request->only('runeed', 'ruamount');
    $food->mavads = ["en" => $enmavad, "ru" => $rumavad];

but I get the error and no correct update


Solution

  • @foreach($food->mavads['en'] as $m)
          <input type="text" class="input" name="enneed[]" value="{{ $m['need'] }}">
          <input type="text" class="input" name="enamount[]" value="{{ $m['amount'] }}">
    @endforeach
    

    When you submit, the values will be wrap in array for the key enneed and enamount, look like this:

    [
      'enneed' => ['enn1', 'enn2'],
      'enamount' => ['enm1', 'enm2']
    ]
    

    So you can change your html to be like this:

    @foreach($food->mavads['en'] as $i => $m)
          <input type="text" class="input" name={{"en[$i][need]"}} value="{{ $m['need'] }}">
          <input type="text" class="input" name={{"en[$i][amount]"}} value="{{ $m['amount'] }}">
    @endforeach
    

    It will return:

    [
      'en' =>[[
        'need' => 'enn1',
        'amount' => 'emn1'
      ],[
        'need' => 'enn2',
        'amount' => 'emn2'
      ]],
    ]
    

    So in your controller, you can directly get the data format:

        $enmavad = $request->only('en');
        $rumavad = $request->only('ru');
        $food->mavads = array_merge($enmavad, $rumavad);