Использовать репозиторий в ограничении?

преамбула


В настоящее время я работаю с коллегой над проектом NestJS, и цель этого проекта - создать систему голосования: создание голосования, участие в нем, получение результатов...

Вы можете глубже взглянуть на мой репозиторий GitHub.

проблема


В текущем состоянии в ядре / сущностях у нас не может быть 2 пользователей в базе данных с одинаковыми именем и фамилией: (firstname && lastname) из-за уникальных ограничений, наложенных на таблицу благодаря typeorm.

Но проблема в том, что в настоящее время create-user.dto.ts не проверяйте, может ли пользователь быть вставлен в таблицу или нет, проверяя, существует ли уже пользователь в таблице с его комбинацией имя / фамилия.

Что я хочу сделать


В настоящее время в нашей системе мы используем class-validator на всех классах dtos проверять параметры из http запросов. Поэтому мы, естественно, изучили документацию, чтобы создать пользовательское ограничение и декоратор, который будет проверять, присутствует ли комбинация имя / фамилия в базе данных с помощью репозитория пользователя.

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) в validate функция, так как наш класс реализует валидацию.

Поэтому здесь мы не знаем, как заставить вещи работать.

Ожидаемое поведение


Ожидаемое поведение заключается в том, что я могу поставить свой декоратор UniqueUser на имущество моего create-user.dto & получить ошибку, как и другие ограничения, когда комбинация имени / фамилии уже существует в базе данных.

1 ответ

Я думаю, вы слишком усложняете это. Было бы лучше просто попытаться вставить, а затем поймать ошибку и сообщить о ней должным образом. В противном случае вы выполняете ненужные операции с вашей базой данных, один раз для первой проверки, а затем снова для вставки. В зависимости от трафика вашего приложения вы все равно можете столкнуться с состоянием гонки, когда вы заранее проверили другой запрос, вызвавший столкновение.

Другие вопросы по тегам