I have an Item, Photo, and ItemPhoto entities with a many-to-many relationship. I'm using TypeORM and class-transformer to convert plain objects to entities.
These are the classes:
@Entity()
export class Item extends BaseModel {
/*
...more fields
*/
@ValidateNested({each: true})
@Type(() => ItemPhoto)
@OneToMany(() => ItemPhoto, itemPhoto => itemPhoto.item , {nullable: true})
photos: ItemPhoto[]
}
@Entity()
export class Photo extends BaseModel {
@IsUrl()
@IsNotEmpty()
@Column({nullable: false})
url: string
}
@Entity()
export class ItemPhoto extends BaseModel {
@IsDefined()
@Type(() => Item)
@ManyToOne(() => Item, (item) => item.photos, {nullable: false})
item: Item
@IsDefined()
@Type(() => Photo)
@ManyToOne(() => Photo, {nullable: false})
photo: Photo
}
and I have a DTO entity for HTTP requests to create an Item:
export class ItemDto {
/*
...more fields
*/
@ArrayNotEmpty()
@IsUrl({}, {each: true})
photos: string[]
toItemEntity() {
const {photos, ...rest} = this
return plainToInstance(Item, {
...rest,
photos: plainToInstance(ItemPhoto, photos.map((photoUrl) => ({
photo: plainToInstance(Photo, { url: photoUrl }),
item: // <-- this is where I strugle to understand
}))),
})
}
}
my questions is, how do I create the ItemPhoto if it needs to get item as one of its properties? Is this code which seems a bit ugly and creates a loop a dicent approach?
toItemEntity() {
const {photos, ...rest} = this
const itemEntity = plainToInstance(Item, {
...rest,
photos: plainToInstance(ItemPhoto, photos.map((photoUrl) => ({
photo: plainToInstance(Photo, { url: photoUrl }),
}))),
})
itemEntity.photos = itemEntity.photos.map(itemPhoto => plainToInstance(ItemPhoto, {
item: itemEntity,
photo: itemPhoto.photo
}))
return itemEntity
}