【问题标题】:How to handle many to many relationship with typeorm and nest.js?如何处理与 typeorm 和 nest.js 的多对多关系?
【发布时间】:2022-11-13 13:37:10
【问题描述】:

我有一个关于 type-orm 和 nest.js 的问题。 我正在尝试在我的玩家模块和我的国家模块之间实现多对多关系。到目前为止效果很好。 我已经在我的 player.entity.ts 中为此创建了关系。这也在我的数据库中为我创建了一个新表。

import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, ManyToMany, JoinTable } from 'typeorm';
import { Team } from '../teams/team.entity';
import { Nation } from '../nations/nation.entity';
import { type } from 'os';

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

  @Column()
  name: string;

  @Column()
  position: string;

  @Column()
  alternatePositions: string;

  @Column()
  placeOfBirth: string;

  @Column()
  age: number;

  @Column({ type: 'date' })
  dateOfBirth: string;

  @Column()
  shirtNumber: number;

  @Column()
  height: number;

  @Column()
  weight: number;

  @Column()
  shooting: string;
  
  @Column()
  contractUntil: number;

  @ManyToOne(() => Team, (team) => team.players)
  team: Team;

  @ManyToMany(() => Nation, { cascade: true })
  @JoinTable({
    name: 'player_nation',
    joinColumn: { name: 'playerId', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'nationId', referencedColumnName: 'id' },
  })
  nations: Nation[];
}

现在当我添加玩家时,我也想添加国家,但这是我的问题。我不明白这现在应该如何工作......

在我的 players.service.ts 中,我创建了以下代码:

import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { Player } from './player.entity';
import { Team } from 'src/teams/team.entity';
import { Nation } from 'src/nations/nation.entity';
import { CreatePlayerDto } from './dtos/create-player.dto';

@Injectable()
export class PlayersService {
    constructor(
        @InjectRepository(Player)
        private repo: Repository<Player>,
        @InjectRepository(Nation)
        private nation: Repository<Nation>,
    ) {}

    async createPlayer(playerDto: CreatePlayerDto, team: Team) {
        const player = this.repo.create(playerDto);
        const nations: Array<Nation> = await this.nation.findByIds(playerDto.nations);
        player.nations = nations;
        player.team = team;
        await this.repo.save(player);
        return player;
    }

    //return all player and their team, league
    async getAllPlayers() {
        return this.repo.find({ relations: ['team', 'team.league'] });
    }

    async getPlayerById(id: number) {
        return this.repo.findOne(id , { relations: ['team', 'team.league'] });
    }

    async updatePlayer(id: number, playerDto: CreatePlayerDto, team: Team) {
        const player = await this.repo.findOne(id);
        this.repo.merge(player, playerDto);
        player.team = team;
        await this.repo.save(player);
        return player;
    }
}

我的 players.controller.ts 看起来像这样:

import { Controller, Post, Body, UseGuards, Get, Put, Delete } from '@nestjs/common';
import { CreatePlayerDto } from './dtos/create-player.dto';
import { PlayersService } from './players.service';
import { AuthGuard } from 'src/guards/auth.guard';
import { TeamsService } from '../teams/teams.service';
import { NationsService } from '../nations/nations.service';

@Controller('players')
export class PlayersController {
    nationsService: any;
    constructor(
        private playersService: PlayersService,
        private teamsService: TeamsService,
    ) {}
    

    @Post()
    @UseGuards(AuthGuard)
    async createPlayer(@Body() body: CreatePlayerDto) {
        const team = await this.teamsService.getTeamById(body.teamId);
        return this.playersService.createPlayer(body, team);
   
    }

    @Get()
    @UseGuards(AuthGuard)
    async getPlayers() {
        return this.playersService.getAllPlayers();
    }

    @Get(':id')
    @UseGuards(AuthGuard)
    async getPlayerById(@Body('id') id: number) {
        return this.playersService.getPlayerById(id);
    }

    @Put(':id')
    @UseGuards(AuthGuard)
    async updatePlayer(@Body('id') id: number, @Body() body: CreatePlayerDto) {
        const team = await this.teamsService.getTeamById(body.teamId);
        return this.playersService.updatePlayer(id, body, team);
    }
}

现在我不知道代码是否像这样工作,我也不知道如何使用 Postman 对其进行测试。

有人能帮我吗?

创建播放器.dto.ts

import { IsNumber, IsString, Min, Max, IsDateString } from "class-validator";

export class CreatePlayerDto {
    @IsString()
    readonly name: string;
    
    @IsString()
    readonly position: string;
    
    @IsString()
    readonly alternatePositions: string;
    
    @IsString()
    readonly placeOfBirth: string;
    
    @IsNumber()
    @Min(12)
    @Max(100)
    readonly age: number;

    @IsDateString({ strict: true })
    dateOfBirth: string;
    
    @IsNumber()
    @Min(1)
    @Max(99)
    readonly shirtNumber: number;
    
    @IsNumber()
    @Min(100)
    @Max(250)
    readonly height: number;
    
    @IsNumber()
    @Min(40)
    @Max(150)
    readonly weight: number;
    
    @IsString()
    readonly shooting: string;
    
    @IsNumber()
    @Min(2023)
    @Max(2050)
    readonly contractUntil: number;

    @IsNumber()
    readonly teamId: number;
    
    nations: [];
}

【问题讨论】:

    标签: typescript nestjs typeorm


    【解决方案1】:

    您必须先创建每个国家,然后将它们添加到播放器并保存

    async createPlayer(playerDto: CreatePlayerDto, team: Team) {
      const nations = [];
      for (let nationDto of playerDto.nations) {
        let nation = this.nationRepo.create(nationDto);
        this.nationRepo.save(nation);
        nations.push(nation);
      }
      const player = this.repo.create(playerDto);
      player.nations = nations;
      player.team = team;
      await this.repo.save(player);
      return player;
    }
    您可以使用邮递员添加您的请求 url http://localhost:3000/players 和 Post 请求类型,并使用您的 createPlayerDto 字段添加正文。

    【讨论】:

    • 非常感谢您的帮助 :) 我更新了我的代码,但现在出现以下错误:[Nest] 35352 - 11/11/2022, 16:03:17 [ExceptionsHandler] playerDto.nations is not iterable +10303ms TypeError: playerDto.nations 不可迭代我必须做什么?
    • 您能否将 CreatePlayerDto 添加到您的问题中以检查国家?
    • 我添加了 CreatePlayerD 对迟到的回复感到抱歉
    猜你喜欢
    • 2021-12-23
    • 2011-02-09
    • 1970-01-01
    • 2020-06-29
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    相关资源
    最近更新 更多