问题
I have two entities - Property and Owner. One Property can have a lot of Owners and Owner can have a lot of Properties. For join use property_owner table. How to update this many-to-many relation using NestJS/TypeORM?
@Entity('property')
export class Property extends EntityModel {
@Column({ length: 255, nullable: false })
name: string;
@ManyToMany(type => Owner, { cascade: true })
@JoinTable({
name: 'property_owner',
joinColumn: { name: 'propertyId', referencedColumnName: 'id'},
inverseJoinColumn: { name: 'ownerId', referencedColumnName: 'id'},
})
owners: Owner[];
}
@Entity('owner')
export class Owner extends EntityModel {
@Column({ length: 255, nullable: false })
name: string;
@ManyToMany(type => Property, { cascade: true })
@JoinTable({
name: 'property_owner',
joinColumn: { name: 'ownerId', referencedColumnName: 'id'},
inverseJoinColumn: { name: 'propertyId', referencedColumnName: 'id'},
})
properties: Property[];
}
Below my service's methods for save and update:
public create(req: Request): Promise<Dto> {
const dto: CreateDto = {
...req.body,
owners: this.formatJoinData(req.body.owners) //[1,2,3] => [{id:1},{id:2},{id:3}]
};
const entity = Object.assign(new Entity(), dto);
return this.repo.save(entity);
}
public update(req: Request): Promise<UpdateResult> {
const dto: EditDto = {
...req.body,
owners: this.formatJoinData(req.body.owners) //[1,2,3] => [{id:1},{id:2},{id:3}]
};
const id = req.params.id;
const entity = Object.assign(new Entity(), dto);
return this.repo.update(id, entity);
}
Saving new Property work fine, but when I try update property I get error
[ExceptionsHandler] column "propertyId" of relation "property" does not exist
Owners data in both cases looks like [{id:1},{id:2},{id:3}]. I think problem in save/update methods results. Save method return to us Entity with id and update method return to us UpdateResult which not contain Entity id. But may be we can transform/additionally define this value somewhere...
回答1:
https://typeorm.io/#/many-to-many-relations documentation doesn't say more than use JoinTable
decorator, and we don't know what you havr in your request, but it looks like you're passing wrong values. These fields are virtual, at the end with m2m relationship third table is created to handle relationship.
回答2:
I found solution. Need to call save method instead update. In my case update will be looks like
import {plainToClass} from 'class-transformer';
public async update(req: Request): Promise<Dto> {
const found = await this.repo.findOneOrFail(req.params.id, {
relations: ['owners', 'electricMeter'],
});
const dto = {
...found,
...req.body,
owners: this.formatJoinData(req.body.owners) //[1,2,3] => [{id:1},{id:2},{id:3}]
updatedBy: this.getUser(req),
updatedDate: Date.now(),
};
return this.repo.save(plainToClass(Entity, dto));
}
This code can be improved, but think that main idea is clear.
来源:https://stackoverflow.com/questions/59771671/nestjs-update-many-to-many-relation-with-join-table