
Laravel 中使用路由模型绑定获取的模型实例后,若仍用 where()->update() 手动查询更新,将绕过模型事件、访问器及批量赋值保护机制,导致数据看似“无错误”却未真正保存——应直接调用模型实例的 update() 方法。
laravel 中使用路由模型绑定获取的模型实例后,若仍用 `where()->update()` 手动查询更新,将绕过模型事件、访问器及批量赋值保护机制,导致数据看似“无错误”却未真正保存——应直接调用模型实例的 `update()` 方法。
在 Laravel 开发中,通过路由模型绑定(如 Stationery $stationery)传入控制器方法的模型实例,本身已是已查询出的 Eloquent 模型对象。此时若错误地使用静态查询构造器(如 Stationery::where(...)->update(...))进行更新,虽然语法合法、无报错、也返回 true,但会跳过模型生命周期钩子(如 updating 事件)、访问器(accessors)、修改器(mutators)以及 $fillable / $guarded 的属性过滤逻辑,更重要的是:它执行的是原始 SQL UPDATE 语句,不触发模型实例的状态变更与脏检查(dirty checking),也无法利用模型内置的保存逻辑(如时间戳自动更新)。
你当前的代码问题正在于此:
Stationery::where('id', $stationery->id)
->update($validated); // ❌ 静态批量更新 —— 绕过模型实例✅ 正确做法是直接调用该绑定模型实例的 update() 实例方法:
public function update(Request $request, Stationery $stationery)
{
$validated = $request->validate([
'category_id' => 'required',
'nama' => 'required',
'satuan' => 'nullable',
'harga' => 'required',
'keterangan' => 'nullable'
]);
$stationery->update($validated); // ✅ 使用实例方法,自动处理 guarded/fillable、事件、时间戳等
return redirect('/barang/pakaihabis')->with('success', 'Data Berhasil Diubah!!');
}? 补充说明:
- Stationery 模型中已设置 protected $guarded = ['id'];,表示除 id 外所有字段均允许批量赋值,因此 $stationery->update($validated) 安全可用;
- 若改用 protected $fillable = ['category_id', 'nama', 'satuan', 'harga', 'keterangan'];,效果一致且更显式推荐;
- update() 实例方法会自动调用 save(),触发 updated 事件、更新 updated_at 时间戳,并确保数据经模型层校验与转换(例如 harga 若定义了 setHargaAttribute mutator,此处将生效)。
? 额外建议:为增强健壮性,可添加更新结果判断:
if ($stationery->update($validated)) {
return redirect('/barang/pakaihabis')->with('success', 'Data Berhasil Diubah!!');
}
return back()->with('error', 'Gagal memperbarui data. Silakan coba lagi.')->withInput();总之,善用路由模型绑定带来的便利——它不只是“查出来一个模型”,更是为你提供了一个可安全、完整操作的 Eloquent 实例。避免混用静态查询与实例操作,是写出清晰、可维护 Laravel 代码的关键习惯。










