@molekulyarniy

Как сделать проверку на дублирующиеся значения в Mongo более элегантной?

До создания нового юзера и добавления его в БД я хочу убедиться, что номер телефона еще не использовался для регистрации, а никнейм еще никем не занят.
В схеме для этих полей прописано unique: true. Но неудобство заключается в том, что при неуспехе валидации в ответ приходит трудночитаемая ошибка, которую нелегко распарсить, чтобы вывести сообщение о том, какое именно поле дублируется (кстати, почему это так? Ошибки с required, например, имеют гораздо более удобную форму).
Еще одно неудобство встроенной валидации на дубликаты заключается в том, что если дублирующихся полей несколько, то в ответ придет ошибка только о первом поле (опять же, в случае с required приходит массив всех незаполненных полей). И это нехорошо для меня, потому что я хочу сразу показать пользователю, какие поля ему нужно изменить. А не шаг за шагом, пока ошибок не будет совсем.
К чему я веду... я написал свой валидатор, но мне он кажется кривым. Хочу знать ваше мнение, как можно его доработать? Или сделать совсем по-другому?
exports.createUser = async (req, res) => {
  try {
    // информация о пользователе, которая пришла из формы
    const incomingData = req.body;

    // массив под поля-дубликаты
    const duplicateErrors = [];

    const nickDuplicate = await User.findOne({
      nickname: incomingData.nickname
    });
    // добавление никнейма в массив дублирующихся полей
    if (nickDuplicate) {
      duplicateErrors.push("nick");
    }

    const numDuplicate = await User.findOne({
      number: incomingData.number
    });
    if (numDuplicate) {
      duplicateErrors.push("num");
    }

    // если хоть одно из полей дублируется - будет отправлена ошибка 400
    if (duplicateErrors.length) {
      return res.status(400).json(duplicateErrors);
    }

    await User.create({
      nickname: incomingData.nickname,
      number: incomingData.number,
      bio: incomingData.bio
    });

    res.status(201).json("success");
  } catch (err) {
    res.status(500).json("Что-то пошло не по плану...");
  }
};

Особенно мне не нравится конструкция такого типа:
const nickDuplicate = await User.findOne({
      nickname: incomingData.nickname
    });
    // добавление никнейма в массив дублирующихся полей
    if (nickDuplicate) {
      duplicateErrors.push("nick");
    }

Обратно на страницу я передаю массив полей, значения которых уже встречаются в БД. Уже на странице, отталкиваясь от содержания полученного массива, я вывожу сообщения под соответствующими инпутами
  • Вопрос задан
  • 45 просмотров
Решения вопроса 1
Два запроса можно объединить в один (ИЛИ), а конкретное поле выявить сравнением. Плюс возвращать не все поля, а только необходимые для сравнения.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы