adonisjs/lucid

afterSave hook empty $dirty property

Closed this issue · 2 comments

Package version

21.5.1

Describe the bug

Property $dirty is empty on after hooks (afterSave). This works fine on beforeSave hook.

This worked fine in older releases of Adonis.js 4.1.

Reproduction repo

No response

I believe this might be intentional. You can find similar behavior in other frameworks, like Laravel.

The $dirty property keeps track of attributes that have changed compared to their original values. However, once you save the model, those changes are committed, and the attributes now match their original values. As a result, there are no longer any "dirty" attributes to track.

get $dirty(): any {
const processedKeys: string[] = []
/**
* Do not compute diff, when model has never been persisted
*/
if (!this.$isPersisted) {
return this.$attributes
}
const dirty = Object.keys(this.$attributes).reduce((result: any, key) => {
const value = this.$attributes[key]
const originalValue = this.$original[key]
let isEqual = true
if (isObject(value) && 'isDirty' in value) {
isEqual = !value.isDirty
} else {
isEqual = compareValues(originalValue, value)
}
if (!isEqual) {
result[key] = value
}
if (this.fillInvoked) {
processedKeys.push(key)
}
return result
}, {})
/**
* Find negative diff if fill was invoked, since we may have removed values
* that exists in originals
*/
if (this.fillInvoked) {
Object.keys(this.$original)
.filter((key) => !processedKeys.includes(key))
.forEach((key) => {
dirty[key] = null
})
}
return dirty
}

I would recommend storing the dirty values before saving if you need them later in the code.

I believe this might be intentional. You can find similar behavior in other frameworks, like Laravel.

The $dirty property keeps track of attributes that have changed compared to their original values. However, once you save the model, those changes are committed, and the attributes now match their original values. As a result, there are no longer any "dirty" attributes to track.

get $dirty(): any {
const processedKeys: string[] = []
/**
* Do not compute diff, when model has never been persisted
*/
if (!this.$isPersisted) {
return this.$attributes
}
const dirty = Object.keys(this.$attributes).reduce((result: any, key) => {
const value = this.$attributes[key]
const originalValue = this.$original[key]
let isEqual = true
if (isObject(value) && 'isDirty' in value) {
isEqual = !value.isDirty
} else {
isEqual = compareValues(originalValue, value)
}
if (!isEqual) {
result[key] = value
}
if (this.fillInvoked) {
processedKeys.push(key)
}
return result
}, {})
/**
* Find negative diff if fill was invoked, since we may have removed values
* that exists in originals
*/
if (this.fillInvoked) {
Object.keys(this.$original)
.filter((key) => !processedKeys.includes(key))
.forEach((key) => {
dirty[key] = null
})
}
return dirty
}

I would recommend storing the dirty values before saving if you need them later in the code.

Thank you for explanation.