Как добавить несколько ссылок на объекты перед сохранением записи с помощью Mongoose и Node? - PullRequest
0 голосов
/ 10 ноября 2019

Я сохраняю запись в своей базе данных MongoDB и сталкиваюсь с ошибкой многократного сохранения при попытке добавить несколько ссылок на объекты в запись.

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

Вот код, с которым я работаю.

СХЕМА МЕНЮ

const MenuSchema = new Schema({
  description: String,
  title: String,
  notes: String,
  _menuItems: [
    {
      type: mongoose.Schema.Types.ObjectId,
      ref: "menuItems"
    }
  ]
});

mongoose.model("menus", MenuSchema);
module.export = MenuSchema;

ПУНКТ МЕНЮ СХЕМА

const MenuItemSchema = new Schema({
  imageURL: String,
  name_en: String,
  name_es: String,
  type_en: String,
  type_es: String,
  description_en: String,
  description_es: String,
  dietaryCallouts: [String],
  price: Number
});

mongoose.model("menuItems", MenuItemSchema);

module.export = MenuItemSchema;

КОНТРОЛЛЕР МЕНЮ

create(req, res, next) {
    try {
      const { description, title, notes } = req.body;
      const { _menuItems } = req.body;

      const menu = new Menu({
        description,
        title,
        notes,
        _menuItems: []
      });

      let counter = 0;
      _menuItems.forEach(function(i) {
        counter++;
        MenuItem.findOne({ _id: i }).then(menuItem => {
          menu._menuItems.push(menuItem);
          if (counter === _menuItems.length) {
            menu.save().then(menu => {
              res.send(menu);
            });
          }
        });
      });
    } catch (err) {
      res.status(422).send(err);
    }
  }

Ожидаемый результат выполнения кода - циклвсе идентификаторы menuItems, найдите их в соответствующей модели, поместите в массив _menuItems и после добавления всех элементов сохраните объект меню.

Я получаю сообщение об ошибке: «ParallelSaveError: Невозможно сохранить () один и тот же документ несколько раз параллельно».

Объект сохранен, но только один из пунктов меню был сохранен в базе данных вместо всех.

По какой-то причине функция сохранения вызывается несколько раз, даже еслиЛогический поток должен выполняться только один раз.

Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 10 ноября 2019

Как я понимаю, вы пытаетесь создать новое меню с заданными элементами меню.

Таким образом, вы делаете это просто так: (нет необходимости в цикле)

router.post("/create-menu-and-items", async (req, res, next) => {

  try {
    const { description, title, notes, _menuItems } = req.body;

    let menu = new Menu({ description, title, notes, _menuItems });
    menu = await menu.save();

    res.status(201).send(menu);

  } catch (err) {
    console.log(err);
    res.status(422).send(err);
  }
});

При этом при публикации на этот URL-адрес ответ будет таким (я предполагаю, что вы отправите существующие идентификаторы пунктов меню в теле:

{
    "_menuItems": [
        "5dc81674ed5a8a3f78356779",
        "5dc81680ed5a8a3f7835677a",
        "5dc8168bed5a8a3f7835677b"
    ],
    "_id": "5dc8180990b714224462fb2b",
    "description": "Menu 1 description",
    "title": "Menu 1 title",
    "notes": "Menu 1 notes",
    "__v": 0
}

Это будет дополнительная информация, но если в будущемВы хотите добавить пункты меню в существующее меню, вы можете сделать так:

router.post("/add-menu-items-to-menu/:id", async (req, res, next) => {

  try {
    const { _menuItems } = req.body;

    let menu = await Menu.findByIdAndUpdate(req.params.id, { $push: { _menuItems } }, { new: true });

    if (menu) {
      res.status(200).send(menu);
    } else {
      res.status(400).send("Menu not found for this id");
    }

  } catch (err) {
    console.log(err);
    res.status(422).send(err);
  }
});

Тело:

{

    "_menuItems": ["5dc81694ed5a8a3f7835677c", "5dc816a5ed5a8a3f7835677d"]
}

Ответ:

{
    "_menuItems": [
        "5dc81674ed5a8a3f78356779",
        "5dc81680ed5a8a3f7835677a",
        "5dc8168bed5a8a3f7835677b",
        "5dc81694ed5a8a3f7835677c",
        "5dc816a5ed5a8a3f7835677d"
    ],
    "_id": "5dc81b134c92ae2884c2468c",
    "description": "Menu 1 description",
    "title": "Menu 1 title",
    "notes": "Menu 1 notes",
    "__v": 0
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...