You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中向已存在数组类型字段追加值失败,更新时被覆盖

解决Laravel数组类型字段追加值被替换的问题

你的问题出在更新时直接用新的JSON字符串覆盖了原有字段,没有做合并操作。以下是几种可行的解决方案:

方法一:取出模型实例合并后更新

先查询到对应的记录,取出原有数组,和新数据合并后再保存,适合需要对数据做去重、过滤等处理的场景:

public function mergeSkillToArtisan(Request $request){
    $identity = $request->post("identity");
    $newSkillIds = $request->post("skillAssessment", []); // 默认空数组避免报错

    // 查找对应记录,不存在则创建
    $record = SkillAssessmentMerging::firstOrNew(['user_id' => $identity]);

    // 取出原有技能ID数组(如果字段为空,默认空数组)
    $existingIds = $record->skill_assessment_ids ?: [];

    // 合并数组并去重(不需要去重可去掉array_unique)
    $mergedIds = array_unique(array_merge($existingIds, $newSkillIds));

    // 赋值保存(如果模型定义了修改器,无需手动json_encode)
    $record->skill_assessment_ids = $mergedIds;
    $record->save();
}

方法二:利用数据库JSON函数直接更新(MySQL为例)

如果你的数据库支持JSON操作(比如MySQL 5.7+),可以直接在数据库层面完成合并,不用取出模型:

public function mergeSkillToArtisan(Request $request){
    $identity = $request->post("identity");
    $newSkillIds = $request->post("skillAssessment", []);

    if(SkillAssessmentMerging::where("user_id", $identity)->exists()){
        // 用JSON_MERGE_PRESERVE合并数组,JSON_UNIQUE自动去重
        SkillAssessmentMerging::where('user_id', $identity)
            ->update([
                'skill_assessment_ids' => \DB::raw(
                    'JSON_UNIQUE(JSON_MERGE_PRESERVE(skill_assessment_ids, :new_ids))',
                    ['new_ids' => json_encode($newSkillIds)]
                )
            ]);
    }else{
        SkillAssessmentMerging::create([
            'user_id' => $identity,
            'skill_assessment_ids' => json_encode($newSkillIds)
        ]);
    }
}

额外优化建议

  1. 修正查询语法错误:你原代码中whereIn('user_id', $identity)存在问题,若$identity是单个ID(字符串/数字),whereIn需要传入数组,应改为where('user_id', $identity),否则会触发数据库语法错误。
  2. 模型定义访问器/修改器:自动处理JSON与数组的转换,避免重复手动编码解码:
// 在SkillAssessmentMerging模型中添加
public function getSkillAssessmentIdsAttribute($value)
{
    return json_decode($value, true) ?? [];
}

public function setSkillAssessmentIdsAttribute($value)
{
    $this->attributes['skill_assessment_ids'] = json_encode((array)$value);
}

之后直接操作数组即可,无需再手动调用json_encode/json_decode。

内容的提问来源于stack exchange,提问作者etranz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:22:33