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

Laravel 9中使用updateOrCreate如何保留created_by不被更新?

解决Laravel 9中updateOrCreate仅创建时赋值created_by的问题

针对你的需求,这里有两种直接可行的方案,不用额外复杂逻辑:

方案一:用firstOrNew手动处理创建/更新逻辑

直接先查询记录,判断是否存在,不存在时再赋值created_by,避免更新时覆盖:

$settings = Settings::firstOrNew([
    'company_uuid' => Auth::user()->company_uuid,
    'setting_type' => 1
]);

// 只有记录不存在(即将创建)时才赋值created_by
if (!$settings->exists) {
    $settings->created_by = Auth::user()->name;
}

// 统一更新需要修改的字段
$settings->setting_bool = $bool_value;
$settings->updated_by = Auth::user()->name;
$settings->save();

这种方式逻辑清晰,完全可控,不会出现你之前遇到的三个问题:既不会因为created_by加入查询条件生成新记录,也不会在更新时覆盖它,创建时也能正确赋值避免数据库报错。

方案二:利用模型creating事件自动赋值

在Settings模型中定义creating事件,让系统在创建新记录时自动填充created_by,这样updateOrCreate的代码就可以简化,不用手动处理:

首先在app/Models/Settings.php中添加事件监听:

protected static function booted()
{
    static::creating(function ($model) {
        // 仅在创建新记录时赋值created_by
        $model->created_by = Auth::user()->name;
    });
}

然后你的updateOrCreate代码可以改成这样:

$company_settings = Settings::updateOrCreate(
    [  
       'company_uuid' => Auth::user()->company_uuid, 
       'setting_type' => 1
    ],
    [
       'setting_bool' => $bool_value, 
       'updated_by' => Auth::user()->name
    ]
);

这个方案的好处是一劳永逸,所有创建Settings记录的场景都会自动填充created_by,不用重复写赋值逻辑,也完全符合你“仅创建时赋值,更新不修改”的需求。

为什么你之前的方法不行?

  • 把created_by放进查询条件数组:每次更新时,查询条件会包含created_by,如果当前操作人不是原创建者,就查不到旧记录,自然会生成新记录。
  • 放进更新数组:updateOrCreate在更新时会把数组里的所有字段都覆盖,所以每次更新都会修改created_by。
  • 完全省略:数据库中created_by字段没有默认值,创建时必须赋值,所以会报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:52:16