如何在Laravel的Model中设置插入更新时自动填充数据库字段?
实现步骤
1 先修正控制器代码
原来的控制器中使用insert()方法是查询构造器方法,不会触发模型事件,无法触发自动填充逻辑,同时存在变量名错误,调整后代码如下:
public function store(Request $request) { $req = Validator::make($request->all(), [ 'name' => 'required', 'order' => 'required', ]); if ($req->fails()) { return response()->json(['error' => $req->errors()], 400); } // 仅取需要的字段,避免恶意参数传入 $data = $request->only(['name', 'order']); // 使用模型的create方法触发模型事件 Post::create($data); return response()->json(['message' => '创建成功'], 201); }
2 单模型直接在Model层配置(适合仅单个模型需要该逻辑)
直接在Post模型中注册创建、更新事件即可,完整代码如下:
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Auth; class Post extends Model { // 关闭Laravel默认的下划线命名时间戳自动维护 public $timestamps = false; // 配置允许批量赋值的字段 protected $fillable = [ 'name', 'order', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy' ]; protected static function boot() { parent::boot(); // 新增数据前自动填充字段 static::creating(function ($model) { $model->createdAt = now(); // 已登录场景下填充操作人ID,未登录可根据业务调整默认值 if (Auth::check()) { $model->createdBy = Auth::id(); } }); // 更新数据前自动填充字段 static::updating(function ($model) { $model->updatedAt = now(); if (Auth::check()) { $model->updatedBy = Auth::id(); } }); } }
3 多模型复用场景使用观察者(推荐)
如果多个模型都需要自动填充操作人和时间字段,使用观察者可以复用逻辑:
3.1 生成观察者类
执行Artisan命令:php artisan make:observer PostObserver --model=Post
3.2 编写观察者逻辑
打开app/Observers/PostObserver.php填入以下代码:
<?php namespace App\Observers; use App\Models\Post; use Illuminate\Support\Facades\Auth; class PostObserver { public function creating(Post $post) { $post->createdAt = now(); if (Auth::check()) { $post->createdBy = Auth::id(); } } public function updating(Post $post) { $post->updatedAt = now(); if (Auth::check()) { $post->updatedBy = Auth::id(); } } }
3.3 注册观察者
打开app/Providers/EventServiceProvider.php,在$observers属性中注册:
protected $observers = [ Post::class => PostObserver::class, ];
注意事项
- 所有需要触发自动填充的操作,必须使用模型方法(
create/save/update),使用查询构造器的insert/update方法不会触发模型事件,无法自动填充 - 批量更新场景不走模型事件,该方案不适用,可根据业务选择SQL触发器或封装自定义查询方法实现
- 未登录场景下操作人字段会留空,可根据自身业务需求调整默认值
内容的提问来源于stack exchange,提问作者Miedkes
相关产品推荐
相关产品推荐

