在约束中使用存储库?

时间:2019-02-08 20:43:20

标签: javascript typescript nestjs typeorm class-validator

序言


我目前正在与一位同事一起进行NestJS项目,该项目的目的是创建一个投票系统,即:创建投票,参与投票,获得结果...

您可以更深入地了解我的github repository

问题


在核心/实体的当前状态下,由于typeorm在表上施加了独特的约束,因此在数据库中不能有2个用户具有相同的名和姓:(firstname && lastname)

但是问题在于,create-user.dto.ts当前不通过检查用户的名字/姓氏组合是否存在于表中来检查用户是否可以插入表中。

我想做什么


当前,在我们的系统中,我们在所有dtos类上使用class-validator来检查来自http请求的参数。因此,我们自然而然地查看了文档以创建custom constraint & decorator that will check if the combination firstname/lastname is currently in the database by using the user repository.

import { UniqueUserConstraint } from '../constraints/unique-user.constraints';

import {
    ValidationOptions,
    registerDecorator,
} from 'class-validator';
// Decorator
export function UniqueUser(validationOptions?: ValidationOptions) {
    return (object: object, propertyName: string) => {
        registerDecorator({
            target: object.constructor,
            propertyName,
            options: validationOptions,
            constraints: [],
            validator: UniqueUserConstraint,
        });
    };
}

import {
    ValidatorConstraint,
    ValidatorConstraintInterface,
    ValidationArguments,
} from 'class-validator';

import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { User } from '../../../core/entities/user.entity';
import { CreateUserDto } from '../dto/create-user.dto';

// Constraint
@ValidatorConstraint({ async: true })
export class UniqueUserConstraint implements ValidatorConstraintInterface {
    constructor(
        @InjectRepository(User)
        private readonly userRepository: Repository<User>,
    ) { }

    async validate(param: any, args: ValidationArguments) {
        const user = args.object as CreateUserDto;
        return await this.userRepository.findOne({
            firstName: user.firstName,
            lastName: user.lastName,
        }).then(find => {
            if (find) return false;
            return true;
        });
    }
}

问题是我们无法访问userRepository,因为它是undefined(因为没有调用构造函数?),我们不能将@InjectRepository(User)放在{{1 }}函数,因为我们的类实现了validate。

所以在这里,我们不知道如何使事情起作用。

预期行为


预期的行为是,我可以将装饰器validate放在我的UniqueUser的属性上,并在数据库中已经存在名/姓组合时像其他约束一样得到错误消息。

1 个答案:

答案 0 :(得分:0)

我认为您对此过于复杂了。最好只是尝试插入然后捕获错误并正确地将其报告回来。否则,您将对数据库执行不必要的操作,一次是第一次检查,然后再次是插入。根据您应用程序的流量,即使您提前检查了另一个正在发生碰撞的请求,您仍可能会遇到竞争状况。