简体   繁体   中英

How to save custom ManyToMany table TypeORM

I'm trying to save an Entity with a custom ManyToMany field in TypeORM

Main Entity

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

  @Column('varchar', { length: 50 })
  name: string;

  @Column('timestamptz')
  creationDate: Date;

  @Column('boolean')
  active: boolean;

  @ManyToOne(
    type => User,
    user => user.routines,
    { eager: false },
  )
  user: User;

  @Column()
  userId: number;

  @OneToMany(
    type => ExerciseToRoutine,
    exerciseToRoutine => exerciseToRoutine.routineId,
  )
  public exerciseToRoutine: ExerciseToRoutine[];
} 

JoinTable

@Entity()
export class ExerciseToRoutine extends BaseEntity {
  @PrimaryColumn()
  exerciseId: number;

  @PrimaryColumn()
  routineId: number;

  @Column()
  day: number;

  @ManyToOne(
    type => Routine,
    routine => routine.exerciseToRoutine,
  )
  routine: Routine;

  @ManyToOne(
    type => Exercise,
    exercise => exercise.exerciseToRoutine,
  )
  exercise: Exercise;
}

Code trying to save Entity

const routine = new Routine(name, currentDate, user, exerciseToRoutine, false);
    await this.trySaveRoutine(routine);

The problem is that I need to save the Routine entity with its exerciseToRoutine (JoinTable to Exercise Entity) before the Routine id is autogenerated, and the property exerciseToRoutine needs that ID. So how Im suposed to do this?? Thanks

A good example of ManyToMany and lazy relation. It will be enough to create user-author-like.entity.ts and implement it where necessary.

Since it uses lazy relations promise, it does not give me a flexible opportunity to use it as I wish. I produced such a solution in my application. I use it in all my GraphQL API.

user.entity.ts

import { Entity, 
        PrimaryGeneratedColumn, 
        Column, 
        BaseEntity, 
        OneToMany, 
        CreateDateColumn, 
        UpdateDateColumn, 
        ManyToMany, 
        JoinTable, 
        OneToOne } from 'typeorm';
import { ObjectType, 
        ID, 
        Field,  
        InputType, 
        ArgsType, 
        Int } from 'type-graphql';
import { Post } from '../post/post.entity';
import { Author } from '../author/author.entity';

@Entity()
@ObjectType()
export class User extends BaseEntity {

    @PrimaryGeneratedColumn('uuid')
    @Field(() => ID)
    id: string;

    @Column({ name: 'userName', unique: true })
    @Field()
    userName: string;

    @Column({ name: 'email', unique: true })
    @Field()
    email: string;

    @Column()
    password: string;

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

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

    // user_author_like
    @ManyToMany(() => Author, author => author.yazariBegenenler, { lazy: true })
    @JoinTable({
        name: 'user_author_like',
        joinColumn: {
            name: 'userId',
            referencedColumnName: 'id'
        },
        inverseJoinColumn: {
            name: 'authorId',
            referencedColumnName: 'id'
        }
    })

    @Field(() => [Author])
    begenilenYazarlar: Promise<Author[]>;
}

author.entity.ts

import { Entity, PrimaryGeneratedColumn, Column, BaseEntity, ManyToMany } from 'typeorm';
import { ObjectType, Field, ID } from 'type-graphql';

import { User } from '../user/user.entity';

@Entity()
@ObjectType()
export class Author extends BaseEntity {

    @PrimaryGeneratedColumn('uuid')
    @Field(() => ID)
    id: string;

    @Column()
    @Field()
    title: string

    // yazari begenenler
    @ManyToMany(() => User, user => user.begenilenYazarlar, { lazy: true })
    @Field(() => [User])
    yazariBegenenler: Promise<User[]>

}

user-author-like.entity.ts

import { BaseEntity, PrimaryColumn, Entity, CreateDateColumn } from 'typeorm';

@Entity()
export class UserAuthorLike extends BaseEntity {

    @PrimaryColumn('uuid')
    userId: string;

    @PrimaryColumn('uuid')
    authorId: string;

    @CreateDateColumn({ type: 'timestamp' })
    likedAt: Date;
}

user-author-like.resolver.ts

import { Resolver, Authorized, Mutation, Arg } from 'type-graphql';
import { UserAuthorLike } from './user-author-like.entity';

@Resolver()
export class UserAuthorLikeResolver {

    @Authorized('ADMIN', 'MODERATOR', 'MEMBER')
    @Mutation(() => Boolean)
    async yazarBegen(
        @Arg('userId') userId: string,
        @Arg('authorId') authorId: string
    ): Promise<Boolean> {
        await UserAuthorLike.create({ userId, authorId }).save();
        return true;
    };

    @Authorized('ADMIN', 'MODERATOR', 'MEMBER')
    @Mutation(() => Boolean)
    async yazarBegenme(
        @Arg('userId') userId: string,
        @Arg('authorId') authorId: string
    ): Promise<Boolean> {
        await UserAuthorLike.delete({ userId, authorId });
        return true;
    };

}

The OneToMany field exerciseToRoutine of Routine does not store any foreign key to ExerciseToRoutine , that will do the join table itself. To save a new Routine entity just set the exerciseToRoutine field to an empty array before. Then create a ExerciseToRoutine with the newly generated Routine id.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM