Skip to content

Commit

Permalink
Merge pull request #1010 from adonisjs/feat/findMany
Browse files Browse the repository at this point in the history
feat(base_model): add findManyBy method
  • Loading branch information
thetutlage authored Mar 13, 2024
2 parents 8c333e0 + e0a2b03 commit 4427c8d
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/orm/base_model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,31 @@ class BaseModelImpl implements LucidRow {
return this.query(options).where(key, value).firstOrFail()
}

/**
* Find multiple models instance using a key/value pair
*/
// @ts-expect-error - Return type should be inferred when used in a model
static findManyBy(clause: Record<string, unknown>, options?: ModelAdapterOptions)
// @ts-expect-error - Return type should be inferred when used in a model
static findManyBy(key: string, value: any[], options?: ModelAdapterOptions)
static findManyBy(
key: string | Record<string, unknown>,
value?: any[] | ModelAdapterOptions,
options?: ModelAdapterOptions
) {
if (typeof key === 'object') {
return this.query(value as ModelAdapterOptions)
.where(key)
.exec()
}

if (value === undefined) {
throw new Exception('"findManyBy" expects a value. Received undefined')
}

return this.query(options).where(key, value).exec()
}

/**
* Same as `query().first()`
*/
Expand Down
17 changes: 17 additions & 0 deletions src/types/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,23 @@ export interface LucidModel {
options?: ModelAdapterOptions
): Promise<InstanceType<T>>

/**
* Find multiple models instance using a key/value pair
*/
findManyBy<T extends LucidModel>(
clause: Record<string, unknown>,
options?: ModelAdapterOptions
): Promise<InstanceType<T>[]>

/**
* Find multiple models instance using a key/value pair
*/
findManyBy<T extends LucidModel>(
key: string,
value: any,
options?: ModelAdapterOptions
): Promise<InstanceType<T>[]>

/**
* Same as `query().first()`
*/
Expand Down
60 changes: 60 additions & 0 deletions test/orm/base_model.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3780,6 +3780,66 @@ test.group('Base Model | fetch', (group) => {
assert.equal(users[1].$primaryKeyValue, 1)
})

test('find many using a clause', async ({ fs, assert }) => {
const app = new AppFactory().create(fs.baseUrl, () => {})
await app.init()
const db = getDb()
const adapter = ormAdapter(db)

const BaseModel = getBaseModel(adapter)

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

@column()
declare username: string

@column()
declare email: string
}

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

const users = await User.findManyBy({ points: 0 })
assert.lengthOf(users, 2)
assert.equal(users[0].$primaryKeyValue, 1)
assert.equal(users[1].$primaryKeyValue, 2)
})

test('find many using a key/value pair', async ({ fs, assert }) => {
const app = new AppFactory().create(fs.baseUrl, () => {})
await app.init()
const db = getDb()
const adapter = ormAdapter(db)

const BaseModel = getBaseModel(adapter)

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

@column()
declare username: string

@column()
declare email: string
}

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

const users = await User.findManyBy('points', 0)
assert.lengthOf(users, 2)
assert.equal(users[0].$primaryKeyValue, 1)
assert.equal(users[1].$primaryKeyValue, 2)
})

test('return the existing row when search criteria matches', async ({ fs, assert }) => {
const app = new AppFactory().create(fs.baseUrl, () => {})
await app.init()
Expand Down

0 comments on commit 4427c8d

Please sign in to comment.