Laravel Eloquent 复现模型时自定义字段调整未生效怎么办
克隆模型自定义字段不生效的解决方案
核心问题原因
自定义字段值被静默丢弃,绝大多数情况是Laravel的批量赋值保护机制导致的。fill()方法仅会对模型$fillable属性白名单内的字段执行赋值操作,如果需要自定义的original_id、order_date、order_time、order_type、order_count不在白名单范围内,或是被模型的$guarded属性拦截,fill()传入的参数会被直接静默忽略,不会抛出任何报错,最终保存的副本会和原模型的字段值完全一致。
可落地的修复方案
- 方案1:手动逐个给模型属性赋值,完全绕开批量赋值限制
这种方式不需要修改模型的批量赋值配置,对现有代码侵入性最低,且赋值会直接写入模型实例属性,能保证观察者在creating、saved等钩子触发时拿到正确的字段值:// 先通过replicate生成无主键的副本实例 $Booking = $model->replicate(); // 直接给属性赋值,不受$fillable规则限制 $Booking->original_id = $this->bookingId; $Booking->order_date = $fields->test_date; $Booking->order_time = $fields->test_time; $Booking->order_type = $fields->test_type; $Booking->order_count = $OrderCount; // 保存前可直接打印属性验证值是否正确 // dd($Booking->getAttributes()); $Booking->save(); - 方案2:调整模型的批量赋值配置,让fill正常生效
如果希望保留原有fill()的链式写法,只需要在对应Booking模型中把自定义用到的字段加入$fillable白名单即可:
配置完成后,原本的链式写法就能正常把自定义值写入模型实例,不会再出现值丢失的问题。// 对应Booking模型内部 protected $fillable = [ // 保留原有其他可填充字段 'original_id', 'order_date', 'order_time', 'order_type', 'order_count', ];
额外注意点
- 正式保存前可以通过
$Booking->getAttributes()打印当前实例的所有待写入属性,确认自定义值已经正确挂载到模型上,再执行save操作,避免因为配置问题导致观察者拿到错误的字段值。 - 如果调整完批量赋值配置后自定义值还是被覆盖,检查这几个字段对应的修改器逻辑,有没有在赋值阶段强制把值重置为原模型的取值。
- 如果原模型的
created_at、updated_at字段不需要保留副本的时间戳,可在replicate后手动重置为当前时间,避免时间逻辑混乱。
内容的提问来源于stack exchange,提问作者Peter Fox
相关产品推荐
相关产品推荐

