MongoDB и Mon goose - идентификатор из двух разных запросов коллекции не совпадает - PullRequest
0 голосов
/ 15 февраля 2020

Я создаю приложение, в котором люди могут ставить «минусы» и приглашать других пользователей в свои минусы. У меня есть простая проблема, но я не смог заставить ее работать:

Я хочу создать маршрут приглашения, который проверяет potluck.attendees, чтобы узнать, были ли они приглашены ранее (и отправлять различные ошибки в зависимости от того, ожидают ли они 0, 1 * посещают или и повторно приглашают их, если они были приглашены ранее, а их статус 2 отклонен), а если нет, то помещают приглашенного в ловушку Массив объектов .attendees и _id потук в массиве объектов user.potlucks приглашенного.

Вот супер-урезанные версии этих двух моделей:

Упрощенная модель Потлака

const PotluckSchema = new Schema({
  attendees: [
    {
      attendeeId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
      },
      status: Number,
      enums: [
        0, //'pending',
        1, //'attending',
        2 //'declined'
      ]
    }
  ]
});

Упрощенная модель пользователя

const UserSchema = new Schema({
  potlucks: [
    {
      potluck: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Potluck'
      }
    }
  ]
});

И что у меня есть на этом маршруте:

router.put('/attendees/invite/:potluckId/:inviteeId', async (req, res) => {
  try {
    const currPotluck = await db.Potluck.findOne({
      _id: req.params.potluckId,
      createdBy: req.user._id
    });
    // Makes sure potluck belongs to user before allowing to invite
    if (!currPotluck)
      return res.status(401).json({
        msg: 'You are not authorized to invite people to this potluck.'
      });
    const invitee = await db.User.findOne({ _id: req.params.inviteeId });

    console.log(currPotluck);
    console.log(invitee);

    for (let i = 0; i < currPotluck.attendees.length; i++) {
      //  Checks if invitee already exists in potluck.attendees
      //  and if their status is 0 or 1 (pending or attending)
      //  It will stop function
      if (
        currPotluck.attendees[i].attendeeId == invitee._id &&
        currPotluck.attendees[i].status == 0 ||
        currPotluck.attendees[i].attendeeId == invitee._id &&
        currPotluck.attendees[i].status == 1
      ) {
        return res.status(401).send({
          error: 'This member has already been invited to your potluck'
        });
      } else if (
        currPotluck.attendees[i].attendeeId == invitee._id &&
        currPotluck.attendees[i].status == 2
      ) {
        //  if their status is 2 (declined)
        //  it will edit their existing object in the attendees array to pending
        //  and re-insert potluck in invitee's user.potlucks model
        await db.Potluck.findOneAndUpdate(
          { _id: currPotluck._id },
          { $set: { 'attendees.$[el].status': 0 } },
          { arrayFilters: [{ 'el.attendeeId': invitee._id }] }
        );
        await db.User.findOneAndUpdate(
          { _id: invitee._id },
          { $push: { potlucks: { potluck: currPotluck._id } } }
        );
        res.send(`This user has been re-invited to your potluck!`);
      }
    }
    // If they don't exist already in potluck.attendees, create new object
    // in potlucks.attendees and user.potlucks for invitee
    await db.Potluck.findOneAndUpdate(
      { _id: currPotluck._id },
      { $push: { attendees: { attendeeId: invitee._id, status: 0 } } }
    );
    await db.User.findOneAndUpdate(
      { _id: invitee._id },
      { $push: { potlucks: { potluck: currPotluck._id } } }
    );
    res.send(`This user has been invited to your potluck!`);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('Server Error');
  }
});

Теперь к вопросу:

Если я запускаю этот код в почтальоне, он запустит два 'findOneAndUpdate', которые идут после for-l oop независимо от того, есть ли совпадение или нет. При попытке отладки, я console.logged оба invitee._id и currPotluck.attendees[i].attendeeId (для теста, где я знал, что приглашенный уже существует в массиве), и они оба появляются как один и тот же идентификатор.

Но если я попытаюсь console.log (currPootluck.attendees[i].attendeeId == invitee._id), он будет false каждый раз. Я сделал «тип» для обоих, и они стали объектами, и они оба выглядят одинаково в console.logs - может быть, строки?

Я знаю, что решение должно быть чем-то очень простым, но я не могу понять, любая помощь будет высоко ценится!

1 Ответ

0 голосов
/ 16 февраля 2020

Обе currPootluck.attendees[i].attendeeId и invitee._id равны ObjectIds, чтобы проверить, совпадают ли они, сначала необходимо преобразовать его в строки.

Это должно выполнить работу: currPootluck.attendees[i].attendeeId.toString() == invitee._id.toString()

...