【问题标题】:NestJs update Many-To-Many relation with join tableNestJs 使用连接表更新多对多关系
【发布时间】:2020-05-03 09:58:50
【问题描述】:

我有两个实体 - 财产和所有者。一个属性可以有很多所有者,而所有者可以有很多属性。对于连接使用 property_owner 表。如何使用 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[];
}

在我的服务的保存和更新方法下方:

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);
  }

保存新属性工作正常,但是当我尝试更新属性时出现错误

 [ExceptionsHandler] column "propertyId" of relation "property" does not exist

两种情况下的所有者数据都类似于 [{id:1},{id:2},{id:3}]。我认为保存/更新方法会导致问题。保存方法返回给我们带有 id 的实体,更新方法返回给我们不包含实体 id 的 UpdateResult。但也许我们可以在某个地方转换/另外定义这个值......

【问题讨论】:

    标签: many-to-many nestjs typeorm


    【解决方案1】:

    我找到了解决方案。需要调用保存方法而不是更新。 在我的情况下,更新看起来像

    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));
      }
    

    此代码可以改进,但认为主要思想很清楚。

    【讨论】:

      【解决方案2】:

      https://typeorm.io/#/many-to-many-relations 文档只说使用 JoinTable 装饰器,我们不知道您的请求中有什么,但看起来您传递了错误的值。这些字段是虚拟的,最后用m2m关系创建第三张表来处理关系。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-08
        • 2019-08-22
        • 2016-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多