diff --git a/src/__tests__/entities/advert.entity.ts b/src/__tests__/entities/advert.entity.ts index a307f86..8e2a2aa 100644 --- a/src/__tests__/entities/advert.entity.ts +++ b/src/__tests__/entities/advert.entity.ts @@ -18,4 +18,17 @@ export class AdvertEntity { @Column({ nullable: true }) entityType: string; + + @PolymorphicParent(() => [UserEntity, MerchantEntity], { + entityTypeColumn: 'creatorType', + entityIdColumn: 'creatorId', + eager: true, + }) + creator: UserEntity | MerchantEntity; + + @Column({ nullable: true }) + creatorId: number; + + @Column({ nullable: true }) + creatorType: string; } diff --git a/src/__tests__/entities/merchant.entity.ts b/src/__tests__/entities/merchant.entity.ts index ed7fd54..d72f2dd 100644 --- a/src/__tests__/entities/merchant.entity.ts +++ b/src/__tests__/entities/merchant.entity.ts @@ -11,4 +11,11 @@ export class MerchantEntity { eager: false, }) adverts: AdvertEntity[]; + + @PolymorphicChildren(() => AdvertEntity, { + entityTypeColumn: 'creatorType', + entityIdColumn: 'creatorId', + eager: false, + }) + createdAdverts: AdvertEntity[]; } diff --git a/src/__tests__/entities/user.entity.ts b/src/__tests__/entities/user.entity.ts index 2253112..fdac57d 100644 --- a/src/__tests__/entities/user.entity.ts +++ b/src/__tests__/entities/user.entity.ts @@ -11,4 +11,11 @@ export class UserEntity { eager: false, }) adverts: AdvertEntity[]; + + @PolymorphicChildren(() => AdvertEntity, { + entityTypeColumn: 'creatorType', + entityIdColumn: 'creatorId', + eager: false, + }) + createdAdverts: AdvertEntity[]; } diff --git a/src/__tests__/polymorphic.repository.spec.ts b/src/__tests__/polymorphic.repository.spec.ts index badec5c..dc8db6b 100644 --- a/src/__tests__/polymorphic.repository.spec.ts +++ b/src/__tests__/polymorphic.repository.spec.ts @@ -179,6 +179,31 @@ describe('AbstractPolymorphicRepository', () => { expect(result?.entityId).toBeNull(); expect(result?.entityType).toBeNull(); }); + + it('Can find entity with customized entity and id columns', async () => { + const repository = AbstractPolymorphicRepository.createRepository( + connection, + AdvertRepository, + ); + const userRepository = connection.getRepository(UserEntity); + + const user = await userRepository.save(new UserEntity()); + + const advert = await repository.save( + repository.create({ + creator: user, + }), + ); + + const result = await repository.findOne({ where: { id: advert.id } }); + + expect(result).toBeInstanceOf(AdvertEntity); + + expect(result?.creator).toBeInstanceOf(UserEntity); + expect(result?.creator.id).toBe(result?.creatorId); + expect(result?.creatorType).toBe(UserEntity.name); + expect(result?.creatorId).toBe(result?.creator.id); + }); }); describe('find', () => { @@ -265,6 +290,38 @@ describe('AbstractPolymorphicRepository', () => { expect(result?.adverts[0].entityType).toBe(UserEntity.name); expect(result?.adverts[0].entityId).toBe(user.id); }); + + it('Can find parent entity with children with customized entity and id columns', async () => { + const repository = AbstractPolymorphicRepository.createRepository( + connection, + UserRepository, + ); + const advertRepository = AbstractPolymorphicRepository.createRepository( + connection, + AdvertRepository, + ); + + const user = await repository.save(new UserEntity()); + + const advert = await advertRepository.save( + advertRepository.create({ + creator: user, + }), + ); + + let result = await repository.findOne({ + where: { id: user.id }, + }); + + result = await repository.hydrateOne(result); + + expect(result).toBeInstanceOf(UserEntity); + expect(result?.createdAdverts).toHaveLength(1); + expect(result?.createdAdverts[0]).toBeInstanceOf(AdvertEntity); + expect(result?.createdAdverts[0].id).toBe(advert.id); + expect(result?.createdAdverts[0].creatorType).toBe(UserEntity.name); + expect(result?.createdAdverts[0].creatorId).toBe(user.id); + }); }); }); }); diff --git a/src/polymorphic.interface.ts b/src/polymorphic.interface.ts index 999fd85..95eb58c 100644 --- a/src/polymorphic.interface.ts +++ b/src/polymorphic.interface.ts @@ -8,7 +8,7 @@ export interface PolymorphicInterface { hasMany: boolean; primaryColumn?: string; entityTypeColumn?: string; - entityTypeId?: string; + entityIdColumn?: string; eager: boolean; cascade: boolean; deleteBeforeUpdate: boolean; @@ -31,7 +31,7 @@ export interface PolymorphicDecoratorOptionsInterface { cascade?: boolean; eager?: boolean; entityTypeColumn?: string; - entityTypeId?: string; + entityIdColumn?: string; } export type PolymorphicChildType = { diff --git a/src/polymorphic.repository.ts b/src/polymorphic.repository.ts index 98fe616..40a9ef5 100644 --- a/src/polymorphic.repository.ts +++ b/src/polymorphic.repository.ts @@ -31,7 +31,7 @@ type PolymorphicHydrationType = { const entityTypeColumn = (options: PolymorphicMetadataInterface): string => options.entityTypeColumn || 'entityType'; const entityIdColumn = (options: PolymorphicMetadataInterface): string => - options.entityTypeId || 'entityId'; + options.entityIdColumn || 'entityId'; const PrimaryColumn = (options: PolymorphicMetadataInterface): string => options.primaryColumn || 'id';