Что делать, если операции после Mon goose findOneAndUpdate завершаются неудачно - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть схема Mon goose, свойство которой представляет собой массив ObjectId дочерних документов.

Если один из этих дочерних документов необходимо удалить / удалить, конечно, я хочу удалить его из свойства массива родителя.

У меня такой вопрос: В каком порядке я выполняю операцию удаления / удаления для дочернего объекта и операцию findOneAndUpdate для родителя?

Причина, по которой я спрашиваю, состоит в том, что если я сначала удаляю / удаляю потомка успешно, но затем получаю ошибку, удаляющую это ObjectId из свойства массива родителя, то кажется, что потомок все еще существует под родителем.

Однако, если я сначала удаляю ObjectId из родительского элемента, а затем возникают проблемы с удалением / удалением дочернего элемента, я не думаю, что есть способ вернуть родительский элемент до удаления этого ObjectId и я бы предпочел, чтобы я не держал осиротевшие документы, если бы мог помочь.

То, что я придумала в этот момент, кажется "хакерским" и может, в свою очередь, произвести его собственные ошибки:

  async deleteForm(req,res,next) {
    let currentLocation;
    try {
      //Remove the reference to the Form from the 'forms' array in the parent 'Location'
      try {
        currentLocation = await Location.findOneAndUpdate(
          {
            forms: mongoose.types.ObjectId(req.params.formId)
          }, 
          {
            $pull: {forms: req.params.formId}
          }
        );
      } catch (err) {
        console.error(err)
        throw new Error('Error removing Form from Location')
      }

      //Actually find and remove the 'Form' itself
      try {
        await Form.findByIdAndRemove(req.params.formId);
      } catch (err) {
        console.error(err);
        /* If the 'Form' can't be removed, re-add the reference to the form back into the 
         parent 'Location's 'forms' array*/
        await currentLocation.update({
          $push: {forms: mongoose.types.ObjectId(req.params.formId)}
        })
        throw new Error('Error deleting Form')
      }

    } catch (err) {
      req.session.error = err;
    } finally {
      res.redirect(`/locations/${currentLocation._id}`);
    }
  }

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Вы можете сначала запустить операцию удаления для дочернего документа, а затем запустить операцию обновления для родительского документа do c. Если вы используете обратные вызовы, вы можете вкладывать 2-ю операцию в блок .then 1-й операции, чтобы гарантировать, что ребенок выполнит c. удаляется перед обновлением родительского do c.

0 голосов
/ 21 апреля 2020

Спасибо @Aviv Lo за напоминание, что обратные вызовы и Promise.then() - это вещь. Честно говоря, я чувствую себя таким новым каждый раз, когда пишу вопрос.

Вот что я закончил:

async deleteForm(req,res,next) {
    let currentLocation;
    try {
      //Find the parent location, to be updated after deleting the form
      try {
        currentLocation = await Location.findOne(
          {
            forms: mongoose.Types.ObjectId(req.params.formId)
          }
        );
      } catch (err) {
        console.error(err)
        throw new Error('Error removing Form from Location')
      } 

      //Actually find and remove the 'Form' itself
      try {
        new Promise(async (resolve, reject) => {
          try {
            await Form.findByIdAndRemove(req.params.formId);
            resolve();
          } catch (err) {
            reject(err);
          }
        })
        /* only after the form is deleted, remove the reference from the parent 
        Location */
        .then(async () => {
          await currentLocation.update({
            $pull: {forms: mongoose.Types.ObjectId(req.params.formId)}
          });
        });
      } catch (err) {
        console.error(err);        
        throw new Error('Error deleting Form')
      }
      req.session.success = 'Form deleted!'
    } catch (err) {
      req.session.error = err;
    } finally {
      res.redirect(`/locations/${currentLocation._id}`);
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...