Более простой способ добавить или обновить глубоко вложенный экземпляр модели - PullRequest
0 голосов
/ 17 ноября 2018

Я работаю с Postgres DB, используя Node / Sequelize. В базе данных есть 3 соответствующих модели: Магазин, Продукт и Предложение. В магазине может быть много товаров, но товар принадлежит одному магазину. Продукты могут иметь много предложений, в то время как предложения принадлежат одному продукту. Чтобы сделать его более сложным, и Продукт, и Предложение имеют своего рода суррогатный Идентификатор, чтобы пользователям было проще связать их с реальными продуктами, а не с автоматически генерируемыми идентификаторами. Таким образом, все продукты должны быть просмотрены по sku, а все предложения по offer_id и предложениям добавляются в продукт через их sku, а не id.

const Product = sequelize.define(
  "product",
  {
    id: {
      type: Sequelize.INTEGER,
      autoIncrement: true,
      allowNull: false,
      primaryKey: true
    },
    sku: {
      type: Sequelize.STRING,
      allowNull: false,
    }
  },
  {
    indexes: [{ fields: ["sku", "storeId"], unique: true }]
  }
);

const Offer = sequelize.define(
  "offer",
  {
    id: {
      type: Sequelize.INTEGER,
      autoIncrement: true,
      allowNull: false,
      primaryKey: true
    },
    offer_id: {
        type: Sequelize.STRING,
        allowNull: false,
      },
    product_sku: {
        type: Sequelize.STRING,
        allowNull: false,
      }
  }
  ,
  {
    indexes: [{ fields: ["offer_id", "productId"], unique: true }]
  }
);

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

function addOffer(newOffer, storeId) {
  //Find a product to add the offer to
  return Product.findOne({
    where: { sku: newOffer.product_sku, storeId: storeId }
  }).then(function(product) {
    if (product) {
      // Product found, check if offer exists
     return Offer
        .findOne({ where: { offer_id: newOffer.offer_id, productId: product.id } })
        .then(function(offer) {
          if (offer) {
            // update offer
            return offer.update({...newOffer });
          } else {
            // insert new offer
            return Offer.create({...newOffer,productId: product.id });
          }
        })
        .catch(err => console.log(err));
    } else {    
      // Product not found
      return false;
    }
  });
}
exports.add_offers = async function(req, res) {
  const storeId = req.body.storeId;
  const offers = [
      {
        "offer_id": "122",
        "product_sku": "5722719"
      },
      {
        "offer_id": "123",
        "product_sku": "5722719"
      },
      {
        "offer_id": "124",
        "product_sku": "5822625"
      }
  ];

  for (const offer of accepted) {
    addOffer(offer, storeId)
      .then(function(result) {
        //res.status(200).send({ success: true });
      })
      .catch(err => {
       //handle error
      });
  }
}

Основная проблема, которую я пытаюсь исправить, - это моя функция addProduct (). Так как я должен сначала найти товар по sku + storeId, чтобы найти productID. Затем проверьте, существует ли предложение уже с offer_id + productId. К тому времени, когда я наконец звоню обновить или создать предложение, я нахожусь на 3 сетевых звонках за предложение. Если мой массив предложений имеет какой-либо значительный размер, он будет невероятно неэффективным.

Есть ли более простой способ?

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