Skip to content

Commit

Permalink
feat(orm): add loadOnce
Browse files Browse the repository at this point in the history
  • Loading branch information
RomainLanz committed Sep 4, 2024
1 parent 870e317 commit 8b40efe
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/orm/base_model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,22 @@ class BaseModelImpl implements LucidRow {
.processAllForOne(this, queryClient)
}

/**
* Load relationships onto the instance, but only if they are not
* already preloaded
*/
async loadOnce(relationName: any) {
this.ensureIsntDeleted()

if (!this.$isPersisted) {
throw new Exception('Cannot lazy load relationship for an unpersisted model instance')
}

if (!this.$preloaded[relationName]) {
return this.load(relationName)
}
}

/**
* @deprecated
*/
Expand Down
6 changes: 6 additions & 0 deletions src/types/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,12 @@ export interface LucidRow {
*/
load: LucidRowPreload<this>

/**
* Load relationships onto the instance, but only if they are not
* already preloaded
*/
loadOnce: LucidRowPreload<this>

/**
* Alias for "load"
* @deprecated
Expand Down
61 changes: 61 additions & 0 deletions test/orm/model_belongs_to.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,67 @@ test.group('Model | BelongsTo | preload', (group) => {
assert.equal(profile.user.id, profile.userId)
})

test('preload once using model instance', async ({ assert, fs }) => {
const app = new AppFactory().create(fs.baseUrl, () => {})
await app.init()
const db = getDb()
const adapter = ormAdapter(db)
const BaseModel = getBaseModel(adapter)

let queryCount = 0

class User extends BaseModel {
@column({ isPrimary: true })
declare id: number
}

class Profile extends BaseModel {
@column({ isPrimary: true })
declare id: number

@column()
declare userId: number

@column()
declare displayName: string

@belongsTo(() => User, {
onQuery() {
queryCount++
},
})
declare user: BelongsTo<typeof User>
}

await db
.insertQuery()
.table('users')
.insert([{ username: 'virk' }])

const users = await db.query().from('users')
await db
.insertQuery()
.table('profiles')
.insert([
{
user_id: users[0].id,
display_name: 'virk',
},
{
user_id: users[0].id,
display_name: 'virk',
},
])

const profile = await Profile.findOrFail(1)
await profile.loadOnce('user')
await profile.loadOnce('user')

assert.instanceOf(profile.user, User)
assert.equal(profile.user.id, profile.userId)
assert.equal(queryCount, 1)
})

test('preload nested relations', async ({ assert, fs }) => {
const app = new AppFactory().create(fs.baseUrl, () => {})
await app.init()
Expand Down

0 comments on commit 8b40efe

Please sign in to comment.