Laravel eloquent 更新 JSON 列的一些字段而不覆盖其他所有字段

Laravel eloquent update JSON column some fields without overriding everything else

我们正在尝试使用 JSON datatypes 来存储 Profile 动态数据,并且不知道要添加到 fillable [=27= 中的所有硬编码字段名称] 在模型中。如何设置(insert if the key not exists | update if the key exists)只有一个键,而不是所有的?

例如,如果我们只想更新 age 并且我们使用:

$model = Profile::find($profile_id);
$model->options = json_encode(['age' => '21']);
$model->save();

此解决方案不是一个很好的选择,因为它会覆盖其他所有内容。 我们如何才能只设置所需的字段而不更改其他字段(JSON 键)?

纯mysql的解是:

UPDATE `profiles`
SET `data` = JSON_SET(
    `data` ,
    '$.age' ,
    '21'
)
WHERE
    `id` = 1;

JSON_SET 函数将添加 属性 如果没有找到,否则替换它。 read more here

但在 Laravel 中,您应该设置模型 $guarded 属性,并删除 $fillable(或留空),然后所有内容都将是 fillable,除了guarded.

那么你可以使用:

Profile::find($profile_id)->update([
   'data->age' => 21,
   'data->gender' => 'male',
]);

there are good experiences here

你也可以使用下面的代码作为:

DB::table('...') with Profile::query()

https://laravel.com/docs/7.x/queries#updating-json-columns