Использовать репозиторий в ограничении?
преамбула
В настоящее время я работаю с коллегой над проектом 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 ответ
Я думаю, вы слишком усложняете это. Было бы лучше просто попытаться вставить, а затем поймать ошибку и сообщить о ней должным образом. В противном случае вы выполняете ненужные операции с вашей базой данных, один раз для первой проверки, а затем снова для вставки. В зависимости от трафика вашего приложения вы все равно можете столкнуться с состоянием гонки, когда вы заранее проверили другой запрос, вызвавший столкновение.