Skip to content

Commit b9c7ec6

Browse files
authored
feat(orm): add saveQuietly (#1093)
1 parent fe43366 commit b9c7ec6

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-1
lines changed

src/orm/base_model/index.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,56 @@ class BaseModelImpl implements LucidRow {
19571957
return this
19581958
}
19591959

1960+
/**
1961+
* Perform save on the model without invoking hooks.
1962+
*/
1963+
async saveQuietly(): Promise<this> {
1964+
this.ensureIsntDeleted()
1965+
const Model = this.constructor as typeof BaseModel
1966+
1967+
/**
1968+
* Persist the model when it's not persisted already
1969+
*/
1970+
if (!this.$isPersisted) {
1971+
this.initiateAutoCreateColumns()
1972+
await Model.$adapter.insert(this, this.prepareForAdapter(this.$attributes))
1973+
1974+
this.$hydrateOriginals()
1975+
this.$isPersisted = true
1976+
1977+
return this
1978+
}
1979+
1980+
/**
1981+
* Call hooks beforehand, so that they have the chance
1982+
* to make mutations that produces one or more `$dirty`
1983+
* fields.
1984+
*/
1985+
const forceUpdate = this.forceUpdate
1986+
this.forceUpdate = false
1987+
1988+
/**
1989+
* Do not issue updates when model doesn't have any mutations
1990+
*/
1991+
if (!this.$isDirty && !forceUpdate) {
1992+
return this
1993+
}
1994+
1995+
/**
1996+
* Perform update
1997+
*/
1998+
this.initiateAutoUpdateColumns()
1999+
2000+
const updatePayload = this.prepareForAdapter(this.$dirty)
2001+
if (Object.keys(updatePayload).length > 0) {
2002+
await Model.$adapter.update(this, updatePayload)
2003+
}
2004+
2005+
this.$hydrateOriginals()
2006+
2007+
return this
2008+
}
2009+
19602010
/**
19612011
* The lockForUpdate method re-fetches the model instance from
19622012
* the database and locks the row to perform an update. The

src/types/model.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,11 @@ export interface LucidRow {
633633
*/
634634
save(): Promise<this>
635635

636+
/**
637+
* Perform save on the model without invoking hooks.
638+
*/
639+
saveQuietly(): Promise<this>
640+
636641
/**
637642
* The lockForUpdate method re-fetches the model instance from
638643
* the database and locks the row to perform an update. The

test/orm/base_model.spec.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* @poppinss/data-models
2+
* @adonisjs/lucid
33
*
44
* (c) Harminder Virk <[email protected]>
55
*
@@ -900,6 +900,59 @@ test.group('Base Model | persist', (group) => {
900900
assert.deepEqual(user.$original, { username: 'virk', fullName: 'H virk', id: 1 })
901901
})
902902

903+
test('do not invoke before and after create hooks when saving quietly', async ({
904+
fs,
905+
assert,
906+
}) => {
907+
assert.plan(1)
908+
909+
const app = new AppFactory().create(fs.baseUrl, () => {})
910+
await app.init()
911+
const db = getDb()
912+
const adapter = ormAdapter(db)
913+
914+
const BaseModel = getBaseModel(adapter)
915+
916+
const stack: string[] = []
917+
918+
class User extends BaseModel {
919+
@column({ isPrimary: true })
920+
declare id: number
921+
922+
@column()
923+
declare username: string
924+
925+
@column()
926+
declare email: string
927+
928+
@beforeCreate()
929+
static beforeCreateHook() {
930+
stack.push('beforeCreateHook')
931+
}
932+
933+
@beforeSave()
934+
static beforeSaveHook() {
935+
stack.push('beforeSaveHook')
936+
}
937+
938+
@afterCreate()
939+
static afterCreateHook() {
940+
stack.push('afterCreateHook')
941+
}
942+
943+
@afterSave()
944+
static afterSaveHook() {
945+
stack.push('afterSaveHook')
946+
}
947+
}
948+
949+
const user = new User()
950+
user.username = 'virk'
951+
await user.saveQuietly()
952+
953+
assert.deepEqual(stack, [])
954+
})
955+
903956
test('merge adapter insert return value with attributes', async ({ fs, assert }) => {
904957
const app = new AppFactory().create(fs.baseUrl, () => {})
905958
const adapter = new FakeAdapter()

0 commit comments

Comments
 (0)