Nestjs / Typeorm добавляет "_rid" к имени моего отношения - PullRequest
0 голосов
/ 05 мая 2020

Я разрабатываю проект с пользователями, у которых есть отношения между учениками и преподавателями. Все шло хорошо, но теперь я не могу опубликовать что-то с его родственником, похоже, Typeorm добавляет "_rid" к имени моих родственников. Я искал, но ничего не нашел. Он отлично работает в отдельном сообщении (например, добавить пользователя), но не работает, когда я пытаюсь создать ученика с уровнем, спортом, датами ...

Controller.ts      
@Post()
      create(
        @Body() createStudentDto: CreateStudentDto,
        @GetUser() user: User,
      ): Promise<void> {
        return this._studentService.createStudent(createStudentDto, user);
      }

Service.ts
createStudent(createStudentDto: CreateStudentDto, user: User): Promise<void> {
    return this._studentRepository.createStudent(createStudentDto, user);
  }

Repository.ts
async createStudent(
    createStudentDto: CreateStudentDto,
    user: User,
  ): Promise<void> {
    const foundUser = await User.findOne(user.id);
    foundUser.details = createStudentDto.details;
    foundUser.sports = createStudentDto.sports;
    foundUser.level = createStudentDto.level;
    foundUser.calendar = createStudentDto.calendar;
    foundUser.save();
  }

CreateStudent.dto.ts
import { Type } from 'class-transformer';
import { Sport } from 'src/modules/sport/sport.entity';
import { Level } from 'src/modules/level/level.entity';
import { UserCalendar } from 'src/modules/calendar/user-calendar.entity';
import { UserDetails } from '../../user.details.entity';

export class CreateStudentDto {
  @Type(type => UserDetails)
  details: UserDetails;

  @Type(type => Sport)
  sports: Sport[];

  @Type(type => Level)
  level: Level;

  @Type(type => UserCalendar)
  calendar: UserCalendar[];
}

import {
  BaseEntity,
  Entity,
  PrimaryGeneratedColumn,
  Column,
  OneToOne,
  JoinTable,
  ManyToMany,
  JoinColumn,
  CreateDateColumn,
  UpdateDateColumn,
  OneToMany,
  ManyToOne,
} from 'typeorm';
import { UserDetails } from './user.details.entity';
import { Role } from '../role/role.entity';
import { status } from '../../shared/entity-status.enum';
import { UserCalendar } from '../calendar/user-calendar.entity';
import { Language } from '../language/language.entity';
import { Target } from '../target/target.entity';
import { StudentTarget } from './student/student-target.entity';
import { Course } from '../course/course.entity';
import { Sport } from '../sport/sport.entity';
import { Level } from '../level/level.entity';

@Entity('users')
export class User extends BaseEntity {
  @PrimaryGeneratedColumn('increment')
  id: number;

  @Column({ type: 'varchar', unique: true })
  email: string;

  @Column({ type: 'varchar' })
  password: string;

  @OneToOne(type => UserDetails, { cascade: true, eager: true })
  @JoinColumn({ name: 'detail_id' })
  details: UserDetails;

  @ManyToMany(
    type => Role,
    role => role.users,
    { eager: true },
  )
  @JoinTable({ name: 'user_roles' })
  roles: Role[];

  @ManyToMany(type => Language, { eager: true })
  @JoinTable({ name: 'user_languages' })
  languages: Language[];

  @ManyToMany(type => Target, { eager: true })
  @JoinTable({
    name: 'student_targets',
    joinColumn: { name: 'student_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'target_id', referencedColumnName: 'id' },
  })
  targets!: Target[];

  @ManyToMany(type => Course, { eager: true })
  @JoinTable({
    name: 'course_students',
    joinColumn: { name: 'student_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'course_id', referencedColumnName: 'id' },
  })
  studentCourses!: Course[];

  @ManyToMany(type => Course, { eager: true })
  @JoinTable({
    name: 'course_instructors',
    joinColumn: { name: 'instructor_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'course_id', referencedColumnName: 'id' },
  })
  instrucorCourses!: Course[];

  @ManyToMany(type => Sport, { eager: true })
  @JoinTable({
    name: 'user_sports',
    joinColumn: { name: 'user_id', referencedColumnName: 'id' },
    inverseJoinColumn: { name: 'sport_id', referencedColumnName: 'id' },
  })
  sports!: Sport[];

  @OneToMany(
    type => StudentTarget,
    studentTarget => studentTarget.validatedBy,
  )
  studentTargetValidations: StudentTarget[];

  @OneToMany(
    type => UserCalendar,
    calendar => calendar.user,
    { eager: true },
  )
  calendar: UserCalendar[];

  @ManyToOne(
    type => Level,
    level => level.users,
    { cascade: true },
  )
  @JoinColumn({ name: 'level_id' })
  level: Level;

  @Column({ type: 'varchar', default: status.ACTIVE, length: 8 })
  status: status;

  @CreateDateColumn({ type: 'timestamp', name: 'created_at' })
  createdAt: Date;

  @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })
  updatedAt: Date;
}

> query failed: SELECT User_targets_rid.target_id AS "target_id", User_targets_rid.student_id AS "student_id" FROM "targets" "targets" INNER JOIN "student_targets" "User_targets_rid" ON (User_targets_rid.student_id = $1 AND User_targets_rid.target_id = "targets"."id") ORDER BY User_targets_rid.target_id ASC, User_targets_rid.student_id ASC -- PARAMETERS: [2]
error: error: missing FROM-clause entry for table "user_targets_rid"

Ошибка запроса

Есть предложения? нужно ли вам знать что-то еще, чтобы помочь мне? Понятия не имею, что могло случиться.

Спасибо

1 Ответ

0 голосов
/ 06 мая 2020

Пример, когда ошибка возникает, а когда не происходит: НЕ ПРОИСХОДИТ

async createStudent(
    createStudentDto: CreateStudentDto,
    user: User,
  ): Promise<void> {
    const foundUser: User = await User.findOne(user.id);
    const level = await Level.findOne(createStudentDto.level.id);
    const targets = await Target.createQueryBuilder('t')
      .innerJoin('t.level', 'l')
      .where('l.order <= :order', { order: level.order })
      .getMany();
    console.log(targets);

    await this.createQueryBuilder()
      .update(UserDetails)
      .set(createStudentDto.details)
      .where('id = :id', { id: foundUser.id })
      .execute();

    await UserCalendar.createQueryBuilder()
      .insert()
      .into('user_calendar')
      .values(createStudentDto.calendar)
      .execute();

    foundUser.sports = createStudentDto.sports;
    foundUser.level = createStudentDto.level;
    foundUser.languages = createStudentDto.languages;
    //foundUser.targets = targets;

    foundUser.save();
  }

ПРОИСХОДИТ, просто не комментируя это:

foundUser.targets = targets;

Когда я не комментирую это строка, появляется эта ошибка:

query failed: SELECT User_targets_rid.target_id AS "target_id", User_targets_rid.student_id AS "student_id" FROM "targets" "targets" INNER JOIN "student_targets" "User_targets_rid" ON (User_targets_rid.student_id = $1 AND User_targets_rid.target_id = "targets"."id") ORDER BY User_targets_rid.target_id ASC, User_targets_rid.student_id ASC -- PARAMETERS: [101]
error: error: missing FROM-clause entry for table "user_targets_rid"

Объекты target и student_targets:

Target.ts
import {
  BaseEntity,
  PrimaryGeneratedColumn,
  Column,
  ManyToMany,
  Entity,
  JoinColumn,
  ManyToOne,
} from 'typeorm';
import { Level } from '../level/level.entity';
import { User } from '../user/user.entity';
import { Sport } from '../sport/sport.entity';

@Entity('targets')
export class Target extends BaseEntity {
  @PrimaryGeneratedColumn('increment')
  id: number;

  @Column({ type: 'varchar', length: 100, nullable: false, unique: true })
  name: string;

  @Column({ type: 'varchar', nullable: true })
  description: string;

  @Column({ name: 'level_id' })
  levelId: number;

  @Column({ name: 'sport_id' })
  sportId: number;

  @ManyToMany(
    type => User,
    user => user.targets,
  )
  students!: User[];

  @ManyToOne(
    type => Level,
    level => level.target,
    { eager: true },
  )
  @JoinColumn({ name: 'level_id' })
  level: Level;

  @ManyToOne(
    type => Sport,
    sport => sport.target,
  )
  @JoinColumn({ name: 'sport_id' })
  sport: Level;
}
Student_Targets.ts
import {
  Entity,
  Column,
  ManyToOne,
  BaseEntity,
  JoinColumn,
  PrimaryColumn,
  CreateDateColumn,
} from 'typeorm';
import { User } from '../user.entity';

@Entity('student_targets')
export class StudentTarget extends BaseEntity {
  @PrimaryColumn({
    name: 'student_id',
    primary: true,
    unique: false,
  })
  studentId!: number;

  @PrimaryColumn({
    name: 'target_id',
    primary: true,
    unique: false,
  })
  targetId!: number;

  @Column({ name: 'validated_by', nullable: true })
  validatedBy: number;

  @CreateDateColumn({ type: 'date' })
  date: Date;

  @Column({ nullable: true })
  feedback: string;

  @ManyToOne(type => User)
  @JoinColumn({ name: 'validated_by' })
  instructor!: User;
}
...