AdonisJS 5中@beforeSave()钩子未触发,inspection_due_date不更新求助
解决AdonisJS 5中inspection_due_date未同步更新的问题
问题根源
- 自动字段时机偏差:AdonisJS的
autoCreate/autoUpdate字段(比如updated_at)是在beforeSave钩子执行完成后才会被设置为最新时间的。这意味着你在beforeSave里读取的inspection.updated_at并不是最终写入数据库的时间,且$dirty.updated_at也不会被标记为脏字段,导致你的判断逻辑无法触发。 - 创建场景判断缺失:当创建新记录时,
updated_at会被自动生成,但此时$dirty.updated_at不会被标记,你的逻辑也不会执行。
修复方案
方案1:直接基于当前时间计算(最可靠)
不需要依赖框架自动生成的updated_at,直接在钩子中生成当前时间来计算到期日,同时覆盖创建和更新场景:
import { DateTime } from 'luxon' @column.dateTime() public inspection_due_date: DateTime @column.dateTime({ autoCreate: true, autoUpdate: true }) public updated_at: DateTime @beforeSave() public static setInspectionDueDate(inspection: Inspection) { const currentTime = DateTime.local() inspection.inspection_due_date = currentTime.plus({ months: 3 }) }
方案2:拆分钩子分别处理创建和更新
如果需要严格和框架生成的updated_at保持时间一致,可以拆分使用beforeCreate和beforeUpdate钩子:
@column.dateTime() public inspection_due_date: DateTime @column.dateTime({ autoCreate: true, autoUpdate: true }) public updated_at: DateTime @beforeCreate() public static setInspectionDueDateOnCreate(inspection: Inspection) { // 创建时直接用框架自动生成的updated_at计算 inspection.inspection_due_date = inspection.updated_at.plus({ months: 3 }) } @beforeUpdate() public static setInspectionDueDateOnUpdate(inspection: Inspection) { // 更新时生成和框架updated_at一致的当前时间 const currentTime = DateTime.local() inspection.inspection_due_date = currentTime.plus({ months: 3 }) }
方案3:手动标记字段为脏(适配原逻辑)
如果坚持使用beforeSave钩子,需要手动标记inspection_due_date为脏字段,确保框架会将其写入数据库:
@beforeSave() public static setInspectionDueDate(inspection: Inspection) { const currentTime = DateTime.local() inspection.inspection_due_date = currentTime.plus({ months: 3 }) // 手动标记字段为脏,强制框架更新该字段 inspection.$dirty.inspection_due_date = true }
额外检查点
- 确认数据库表中
inspection_due_date字段允许为NULL,或创建记录时该字段会被自动赋值(上述方案均满足)。 - 排查是否有其他钩子或业务逻辑覆盖了
inspection_due_date的值。 - 测试更新操作时,可修改任意一个无关字段,验证
inspection_due_date是否同步更新。
内容的提问来源于stack exchange,提问作者hossain45
相关产品推荐
相关产品推荐

