Skip to content

autoUpdate sets timestamp on both Creation and Update #1114

@diego-sepulveda-lavin

Description

@diego-sepulveda-lavin

Package version

21.6.1

Describe the bug

Hi,
I'm observing unexpected behavior with the @column.dateTime decorator in Lucid, specifically with the autoUpdate option. Currently, a column with autoUpdate: true sets the timestamp not only on updates but also on creation, which may not align with the expected behavior.

Expected Behavior
autoCreate: true -> Sets the timestamp on row creation.

autoUpdate: true -> Sets the timestamp only on row updates, not on creation unless combined with autoCreate: true.

Actual Behavior
A column with autoUpdate: true (and no autoCreate) sets the timestamp on both creation and updates.

Details
The behavior stems from the initiateAutoCreateColumns method in src/Orm/BaseModel/index.ts, which checks column.meta.autoCreate || column.meta.autoUpdate when setting timestamps on creation. This causes autoUpdate: true to trigger timestamp setting during creation, which I suspect might be unintended.

Reproduction

import { DateTime } from 'luxon'
import { BaseModel, column } from '@adonisjs/lucid/orm'

export default class Post extends BaseModel {
  @column({ isPrimary: true })
  public id: number

  @column.dateTime({ autoCreate: true })
  public createdAt: DateTime

  @column.dateTime({ autoUpdate: true })
  public updatedAt: DateTime 
}
const post = new Post()
await post.save() // Both createdAt and updatedAt are set
post.title = 'New Title'
await post.save() // updatedAt is updated (expected)

Is This a Bug or Intended?
I'm unsure if this is a bug or intended design. The documentation suggests autoUpdate is for updates, but the current behavior (setting timestamps on both creation and updates) can be achieved by combining autoCreate: true and autoUpdate: true. If autoUpdate is meant to only affect updates, the || column.meta.autoUpdate condition in initiateAutoCreateColumns should be removed.
Additionally, this behavior makes autoUpdate: true impractical for columns that can remain null when no update has occurred, requiring a model hook workaround 👇

@column.dateTime() // no autoUpdate:true here
public updatedAt: DateTime | null

@beforeUpdate()
  public static setUpdatedAtOnUpdate(model: Post) {
    if (model.$isDirty) {
      model.updatedAt = DateTime.local()
    }
  }

Potential Breaking Change
Changing this behavior could be a breaking change for codebases relying on autoUpdate: true to set timestamps on both creation and updates. Such projects would need to update their decorators to use autoCreate: true, autoUpdate: true to maintain the current behavior.

Suggested Fix
If this is a bug, update initiateAutoCreateColumns to check only column.meta.autoCreate:

Please confirm if this is intended or a bug, and whether a fix would be considered. Happy to provide more details or assist with testing!

Reproduction repo

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions