Home > Software design >  nestjs typeorm ManytoMany how to save to a parameter in a related table?
nestjs typeorm ManytoMany how to save to a parameter in a related table?

Time:11-18

I currently have a nestjs service /api/permission To create a new permission I send the following parameters for REQUEST:

{"Id":"","EsName":"rxe2x","EnName":"rxi2x","Name":"rxclv2x","Type":"64","Role":"7,8,9"}

And RESPONSE is

{"status":201,"message":"Permission has been saved successfully.","permission":{"Id":"200","EsName":"rxe2x","EnName":"rxi2x","Name":"rxclv2x","Type":"64","Role":"7,8,9"}}

I want the Role parameter to also be saved, in the PermissionRole table, each role with an entry like this:

RoleId PermissionId
7 200
8 200
9 200

on my permission.service.ts

async createPermission(permission: CreatePermissionDto) {
    const exist = await this.permissionRepository.findOne({
        where: { Name: permission.Name },
    });

    if (exist)
        throw new ConflictException(
            'The permission already exists.',
            HttpStatus.CONFLICT.toString(),
        );

    const newPermission = await this.permissionRepository.save(permission);

    return Object.assign(
        {},
        {
            status: HttpStatus.CREATED,
            message: 'Permission has been saved successfully.',
            permission: newPermission,
        },
    );
}

summary of my Permission.entity.ts

import { Role } from './Role.entity';
@Entity('Permission', { schema: 'dbo' })
export class Permission extends BaseEntity {
    @PrimaryGeneratedColumn({
        type: 'int',
        name: 'Id',
    })
    Id: number;

    @Column('varchar', {
        nullable: false,
        name: 'Name',
    })
    Name: string;

    @Column('int', {
        nullable: false,
        name: 'Type',
    })
    Type: number;

    @Column('varchar', {
        nullable: false,
        name: 'EnName',
    })
    EnName: string;

    @Column('varchar', {
        nullable: false,
        name: 'EsName',
    })
    EsName: string;

    @ManyToMany(
        () => Role,
        (Role: Role) => Role.permissions,
    )
    roles: Role[];
}

summary of my Role.entity.ts

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

@Entity('Role', { schema: 'dbo' })
export class Role extends BaseEntity {
    @PrimaryGeneratedColumn({
        type: 'int',
        name: 'Id',
    })
    Id: number;

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

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

    @Column('bigint', {
        nullable: true,
        name: 'VALAccount',
    })
    VALAccount: string;

    @Column('bit', {
        name: 'CanModified',
        default: '1',
    })
    CanModified: string;

    @ManyToMany(
        () => Permission,
        (Permission: Permission) => Permission.roles,
        {
            nullable: false,
            eager: true,
        },
    )
    @JoinTable({
        name: 'PermissionRole',
    })
    permissions: Permission[];

    @ManyToMany(
        () => User,
        (User: User) => User.roles,
    )
    users: User[];

    @ManyToMany(
        () => User,
        (User: User) => User.rolesCanAssign,
    )
    usersCanAssign: User[];
}

CodePudding user response:

You have to define many to many like this in Permission.entity.ts

 @ManyToMany(() => Role , (role) => role.id)
  @JoinTable({
    name: 'Permission_Role',
    joinColumn: {
      name: 'permissionId',
      referencedColumnName: 'id'
    },
    inverseJoinColumn: {
      name: 'roleId',
      referencedColumnName: 'id'
    }
  })
  roles: Role[];

And in permission.service.ts

async createPermission(permission: CreatePermissionDto) {
    const exist = await this.permissionRepository.findOne({
        where: { Name: permission.Name },
    });

    if (exist)
        throw new ConflictException(
            'The permission already exists.',
            HttpStatus.CONFLICT.toString(),
        );

    const newPermissionDao = this.permissionRepository.create(permission);

    newPermissionDao.roles = permission.roles.map((role) => {roleId: role, permissionId: newPermissionDao.id} );
    const newPermission = await this.permissionRepository.save(newPermissionDao);

    return Object.assign(
        {},
        {
            status: HttpStatus.CREATED,
            message: 'Permission has been saved successfully.',
            permission: newPermission,
        },
    );
}

Basically you need to create an array of object for many to many relation like below:

permission.roles = [{
  roleId: 1,
  permissionId: 1
 },
 {
  roleId: 2,
  permissionId: 1
 }];
  • Related