首页 > 解决方案 > 在 Laravel Eloquent 中更新 JSON 嵌套值

问题描述

我需要使用 Laravel Eloquent 更新 JSON 的一些嵌套值,但没有得到我想要的优化结果。下面的json需要经常更新。我对此有一个可行的解决方案,但需要微调解决方案。

{
  "a": {
    "b": 12,
    "c": 792,
    "d": 45,
    "e": {
      "1": {
        "name": "Guna",
        "city": "city1",
        "dob": 2000
      },
      "2": {
        "name": "Raj",
        "city": "city2",
        "dob": 2001
      },
      "3": {
        "name": "Dhamu",
        "city": "city3",
        "dob": 1985
      },
      "4": {
        "name": "Bhavi",
        "city": "city5",
        "dob": 1985
      }
    }
  }
}

尝试过的代码

$c_array=Json::decode($this->company->details, 1);
$c_array['a']['Player'][$p[0]]['st']=$p[1];
$c_array['a']['e'][1]['name'] = 'Bheem';
$c_array['a']['e'][1]['city'] = 'City10';
$c_array['a']['e'][2]['name'] = 'Dhanu';
$c_array['a']['e'][2]['city'] = 'City5';
$this->company()->update(['details' => Json::encode($c_array)]);

上面的代码工作正常,但是在检查查询时整个 json 都会更新。我只需要更新需要更新的各个键。

我们可以使用 Query Builder (DB::raw) 更新代码,如下所示,

update ultimate_squad set squad=JSON_SET(details,'$.a.e."1".name','Bheem','$.a.e."1".city','City10','$.a.e."2".name','Dhanu','$.a.e."2".city','City5') where c_id=1;

标签: phpmysqllaraveleloquentmysql-json

解决方案


是的,如果使用 JSON 转换,使用 Eloquent 可以更新单个属性:

class User extends Model
{
    protected $casts = [
        'options' => 'array',
    ];
}
$user = User::find(1);

$user->update(['options->enabled' => true]);

https://laravel.com/docs/8.x/eloquent-mutators#array-and-json-casting

如果您需要批量分配,您还应该将其添加到可填充

protected $fillable = [
    'options->enabled',
];

https://laravel.com/docs/8.x/eloquent#mass-assignment-json-columns

此外,您可以通过使用预定义的类或创建您自己的自定义类实现Illuminate\Contracts\Database\Eloquent\Castable返回您自己的逻辑来为您的 JSON 字段创建更详细的解析。

use Illuminate\Database\Eloquent\Casts\AsArrayObject;

protected $casts = [
    'options' => AsArrayObject::class,
];

https://laravel.com/docs/8.x/eloquent-mutators#array-object-and-collection-casting


推荐阅读