crud icon indicating copy to clipboard operation
crud copied to clipboard

NestJS: Update the relational tree object [ManyToMany relation between Entities]

Open ahmadraza-gh opened this issue 4 years ago • 2 comments

I am trying to run the update function from a repository like this.userRepository.update(1, User) this User object contains the relational tables data as well. like { id: 1, name: 'test', positions: [{id: 1}, {id: 2}] }

My Schemas are like

User Schema

  @Entity()
export class User extends BaseEntity {
  @ApiPropertyOptional()
  @PrimaryGeneratedColumn()
  id: number;

  @ApiPropertyOptional()
  @Column()
  name: string;

  @ManyToMany(type => Position, {cascade: ['update']})
  @JoinTable({
    name: "rel_user_position",
    joinColumn: { name: 'userId', referencedColumnName: 'id'},
    inverseJoinColumn: { name: 'posId', referencedColumnName: 'id'},
  })
  positions: Position[]

  @ApiPropertyOptional()
  @CreateDateColumn()
  createdAt: Date;
}

Position Schema

@Entity()
export class Position extends BaseEntity {
  @ApiPropertyOptional()
  @PrimaryGeneratedColumn()
  id: number;

  @ApiPropertyOptional()
  @Column()
  status: string;

  @ManyToMany(type => User, {cascade: true})
  @JoinTable({
    name: "rel_user_position",
    joinColumn: { name: 'posId', referencedColumnName: 'id'},
    inverseJoinColumn: { name: 'userId', referencedColumnName: 'id'},
  })
  users: User[];
}

When I run the update query it gives error as QueryFailedError: column "userId" of relation "user" does not exist. but this userId is in the relational table rel_user_position.

How can i resolve this issue ?

ahmadraza-gh avatar Aug 09 '20 19:08 ahmadraza-gh

Hello, have you resolved your problem? I encountered the same problem

greenking19 avatar Apr 10 '23 14:04 greenking19

EDIT: just try this.userRepository.save({ id, ...dto })

OLD: try it

User Schema

@Entity()
export class User {
 @ApiPropertyOptional()
 @PrimaryGeneratedColumn()
 id: number;

 @ApiPropertyOptional()
 @Column()
 name: string;

 @ManyToMany(type => Position, {cascade: ['update']})
 @JoinTable()
 positions: Position[]

 @ApiPropertyOptional()
 @CreateDateColumn()
 createdAt: Date;
}

Position Entity

@Entity()
export class Position extends BaseEntity {
  @ApiPropertyOptional()
  @PrimaryGeneratedColumn()
  id: number;

  @ApiPropertyOptional()
  @Column()
  status: string;

  @ManyToMany(type => User)
  @JoinTable()
  users: User[];
}

Many to many cannot across update

For update u need will find all position for example where DTO status = dto.status like this.positionRepository.exist({ where: { status: dto.status } })

If exist, u need update this like this.positionRepository.update(positionRepo.id, { status: dto.status }) If not exists, u need create new and create relation between user and position

Or you can describe in the model itself what is needed when processing onUpdate in the Position Entity, describe there exactly how to respond to update, that is, what is described above there, and not the Patch method, I think this approach is better suited

Efcolipt avatar May 14 '23 19:05 Efcolipt