Laravel创建记录时自动填充无默认值非空字段的最佳方案
代码不生效的核心原因
- 你把
auth()->user()的判断写在了booted方法的根层级,booted方法只会在框架启动、模型首次加载时执行一次,此时请求还未完成解析,绝大多数场景下auth()是未初始化的,判断直接不通过,导致creating事件回调根本没有被注册,自然不会触发。 - 回调中错误使用了
self::name获取字段值,self指代的是User模型类本身,不是你当前正在创建的模型实例,无法拿到本次写入要用到的name参数,要使用回调参数传入的$model实例获取属性。
creating事件触发时机
Laravel Eloquent的creating事件在数据写入数据库之前触发,此时你传入create方法的所有参数已经完成赋值到模型实例,修改$model的属性会直接被带入最终的INSERT语句,刚好是自动填充字段的最佳时机,完全符合你的需求。
正确实现方案
将判断逻辑移入creating回调内部,使用模型实例获取属性即可:
protected static function booted(): void { self::creating(function ($model) { // 若已经手动传入username则跳过生成,可根据业务需求调整逻辑 if (empty($model->username)) { $model->username = self::generateUsername($model->name); } // 如果你的生成逻辑确实依赖当前登录用户,把auth判断写到这里即可 // if (auth()->check()) { // 你的业务逻辑 // } }); }
注意事项
- 只有走Eloquent模型的写入方法(
create、保存新的Model实例调用save)才会触发模型事件,如果你使用查询构造器的insert()方法直接写入数据,不会触发该回调,需要手动传值。 - 如果自动填充逻辑较多,建议单独创建模型观察者统一管理事件逻辑,代码可维护性更高。
内容的提问来源于stack exchange,提问作者user16275964
相关产品推荐
相关产品推荐

