Search code examples
databasetypescriptmigrationmodelingtypeorm

Mapping many to many relations with typeorm


What I want to do is to show a list of all objects that are related to another entity. In this project, a group has many users and a user has many groups.

Group

@Entity('group')
class Group {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

 @OneToMany(() => GroupMember, groupMember => groupMember.user, {
    eager: true,
  })
  @JoinTable()
  members: User[];

  @CreateDateColumn()
  created_at: Date;

  @UpdateDateColumn()
  updated_at: Date;
}

User

@Entity('user')
class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  first_name: string;

  @Column()
  email: string;

  @OneToMany(() => GroupMember, groupMember => groupMember.group)
  @JoinTable()
  groups: Promise<Group[]>;

  @CreateDateColumn()
  @Exclude()
  created_at: Date;

  @UpdateDateColumn()
  @Exclude()
  updated_at: Date;
}

Group-User

@Entity('group_member')
class GroupMember {
  @PrimaryColumn()
  group_id: string;

  @ManyToOne(() => Group, { primary: true })
  @JoinColumn({ name: 'group_id' })
  group: Promise<Group>;

  @PrimaryColumn()
  user_id: string;

  @ManyToOne(() => User, { primary: true })
  @JoinColumn({ name: 'user_id', referencedColumnName: 'id' })
  user: Promise<User>;

  @CreateDateColumn()
  created_at: Date;

  @UpdateDateColumn()
  updated_at: Date;
}

The behavior I expect is to, with eager loading, I get a list of groups when I search for a user and get a list of users when I search for a group. I know I can't have 'eager' on both sides, but getting to know how to do with only one entity first is enough.

For now, all I'm getting when I search for a group is an empty list.


Solution

  • I've done it in the following way:

    Entity group:

    @OneToMany(() => GroupMember, groupMember => groupMember.groups)
      members: GroupMember[];
    

    Entity user

    @OneToMany(() => GroupMember, groupMember => groupMember.groups)
      groups: GroupMember[];
    

    Entity group_users

      @ManyToOne(() => Group, { primary: true })
      @JoinColumn({ name: 'group_id' })
      groups: Group[];
    
    @ManyToOne(() => User, { primary: true })
      @JoinColumn({ name: 'user_id' })
      users: User[];
    

    How to load those entities in Repository

    findById(group_id: string): Promise<Group | undefined> {
        return this.ormRepository.findOne(group_id, {
          relations: ['members', 'members.users'],
        });
      }