续集打字稿多对多关系模型数据

sat*_*ink 3 postgresql many-to-many sequelize.js typescript

我正在将sequelize与sequ​​elize-typescript库一起使用,并试图实现以下关系:

团队.ts

@Scopes({
  withPlayers: {
    include: [{model: () => User}]
  }
})
@Table
export default class Team extends Model<Team> {

  @AllowNull(false)
  @Column
  name: string;

  @BelongsToMany(() => User, () => TeamPlayer)
  players: User[];
}
Run Code Online (Sandbox Code Playgroud)

用户.ts

@Scopes({
  withTeams: {
    include: [{model: () => Team, include: [ () => User ]}]
  }
})
@Table
export default class User extends Model<User> {

  @AllowNull(false)
  @Column
  firstName: string;

  @AllowNull(false)
  @Column
  lastName: string;

  @BelongsToMany(() => Team, () => TeamPlayer)
  teams: Team[];
}
Run Code Online (Sandbox Code Playgroud)

TeamPlayer.ts

@DefaultScope({
  include: [() => Team, () => User],
  attributes: ['number']
})
@Table
export default class TeamPlayer extends Model<TeamPlayer> {

  @ForeignKey(() => User)
  @Column
  userId: number;

  @ForeignKey(() => Team)
  @Column
  teamId: number;

  @Unique
  @Column
  number: number;
}
Run Code Online (Sandbox Code Playgroud)

现在,当查询玩家时,您将获得具有以下数据的对象:

{
  "id": 1,
  "name": "Doe's Team",
  "players": [
    {
      "id": 1,
      "firstName": "John",
      "lastName": "Doe",
      "TeamPlayer": {
        "userId": 1,
        "teamId": 1,
        "number": 32
    }
 }]
}
Run Code Online (Sandbox Code Playgroud)

现在有几件事我无法完成。

1)我想将其重命名TeamPlayer为“会员资格”;但不是通过更改类的名称2)的内容TeamPlayer不应该有id,但我希望它包含团队的数据,例如:

{
  "firstName": "John",
  "lastName": "Doe"
  "membership": {
     "number": 32
 }
Run Code Online (Sandbox Code Playgroud)

在上面的类中,我尝试将类的范围设置TeamPlayer为仅包含在包含number内部TeamMember,但没有效果。

我曾经让班级拥有和TeamPlayer的直接成员资格,但该解决方案 给班级增加了冗余,并且也没有防止团队中出现重复的成员资格。我确实可以手动(=在代码中)防止这些情况下的重复,但这感觉不太优雅。teamplayeridTeamPlayer

sat*_*ink 6

TeamPlayer我最终通过添加从toUser和 到 的一对多关系解决了这个问题Team,并且还找到了通过添加另外两个字段来使teamId+对唯一的方法,如下所示:userId@ForeignKey

TeamPlayer.ts

@Table
export default class TeamPlayer extends Model<TeamPlayer> {

  @BelongsTo(() => Team)
  team: Team;

  @ForeignKey(() => Team)
  @PrimaryKey
  @Column
  teamId: number;

  @BelongsTo(() => User)
  user: User;

  @ForeignKey(() => User)
  @PrimaryKey
  @Column
  userId: number;

  @Column
  number: number;
}
Run Code Online (Sandbox Code Playgroud)

用户.ts

@Table
export default class User extends Model<User> {

  @AllowNull(false)
  @Column
  firstName: string;

  @AllowNull(false)
  @Column
  lastName: string;

  @HasMany(() => TeamPlayer)
  teams: TeamPlayer[];
}
Run Code Online (Sandbox Code Playgroud)

团队.ts

export default class Team extends Model<Team> {
  @AllowNull(false)
  @Column
  name: string;

  @HasMany(() => TeamPlayer)
  players: TeamPlayer[];
}
Run Code Online (Sandbox Code Playgroud)

该解决方案允许我通过范围控制包含的查询属性,并为我提供正确的对象输出。