feat: implement auto EagerLoads in library (#506)

This commit is contained in:
Manuel Nascimento 2023-03-01 05:02:13 -03:00 committed by GitHub
parent 1ea52d24da
commit 6193ea28df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 1 deletions

View File

@ -261,6 +261,46 @@ const paginateConfig: PaginateConfig<CatEntity> {
}
```
## Eager loading
Eager loading should work with typeorm's eager property out the box. Like so
```typescript
import { Entity, OneToMany } from 'typeorm';
@Entity()
export class CatEntity {
@PrimaryGeneratedColumn()
id: number
@Column('text')
name: string
@Column('text')
color: string
@Column('int')
age: number
@OneToMany(() => CatToyEntity, (catToy) => catToy.cat, {
eager: true,
})
toys: CatToyEntity[]
}
// service
class CatService {
constructor(private readonly catsRepository: Repository<CatEntity>) {}
public findAll(query: PaginateQuery): Promise<Paginated<CatEntity>> {
return paginate(query, this.catsRepository, {
sortableColumns: ['id', 'name', 'color', 'age'],
loadEagerRelations: true // set this property as true to enable the eager loading
})
}
}
```
## Usage with Query Builder
You can paginate custom queries by passing on the query builder:

View File

@ -32,7 +32,9 @@ export class CatEntity {
@Column(() => SizeEmbed)
size: SizeEmbed
@OneToMany(() => CatToyEntity, (catToy) => catToy.cat)
@OneToMany(() => CatToyEntity, (catToy) => catToy.cat, {
eager: true,
})
toys: CatToyEntity[]
@OneToOne(() => CatHomeEntity, (catHome) => catHome.cat, { nullable: true })

View File

@ -1981,4 +1981,24 @@ describe('paginate', () => {
expect(result.data.length).toBe(4)
})
it('should return eager relations when set the property `loadEagerRelations` as true', async () => {
const config: PaginateConfig<CatEntity> = {
sortableColumns: ['id'],
defaultSortBy: [['id', 'ASC']],
loadEagerRelations: true,
searchableColumns: ['name'],
}
const query: PaginateQuery = {
path: '',
search: 'Garfield',
}
const result = await paginate<CatEntity>(query, catRepo, config)
expect(result.data[0].toys).toBeDefined()
expect(result.data[0].toys).toHaveLength(1)
})
})

View File

@ -5,6 +5,7 @@ import {
FindOptionsWhere,
FindOptionsRelations,
ObjectLiteral,
FindOptionsUtils,
} from 'typeorm'
import { PaginateQuery } from './decorator'
import { ServiceUnavailableException, Logger } from '@nestjs/common'
@ -62,6 +63,7 @@ export interface PaginateConfig<T> {
filterableColumns?: {
[key in Column<T>]?: (FilterOperator | FilterSuffix)[]
}
loadEagerRelations?: boolean
withDeleted?: boolean
relativePath?: boolean
origin?: string
@ -146,6 +148,12 @@ export async function paginate<T extends ObjectLiteral>(
const queryBuilder = repo instanceof Repository ? repo.createQueryBuilder('__root') : repo
if (repo instanceof Repository && !config.relations && config.loadEagerRelations === true) {
if (!config.relations) {
FindOptionsUtils.joinEagerRelations(queryBuilder, queryBuilder.alias, repo.metadata)
}
}
if (isPaginated) {
// Switch from take and skip to limit and offset
// due to this problem https://github.com/typeorm/typeorm/issues/5670