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
相关产品推荐
相关产品推荐

