Как передать идентификатор в связанные записи с Sequelize - PullRequest
0 голосов
/ 25 мая 2018

Я создаю приложение с Express на бэкэнде, Postgres для дБ и Sequelize для ORM.

У меня есть 3 связанные модели:

Post
Event
Publishing, принадлежит Post, принадлежит Event

Когда я публикую свой Post, я обновляю его состояние до 2, мне нужно создать Event и Publishing,Publishing будет иметь postId и eventId, среди прочего, которые я передаю с запросом.Я попробовал следующий код, он изменяет состояние сообщения, создает событие и публикацию, но они не связаны друг с другом.

  publishPost(req) {
    return new Promise((resolve, reject) => {
      async.parallel({
        changeState: (callback) => {
          Post.findAll({
            where: { id: req.query.post_id },
            attributes: ['id', 'state']
          })
          .then((updateState) => {
            updateState.forEach((postState) => {
              postState.updateAttributes({ state: 2 });
            });
          })
          .then((updatedState) => {
            callback(null, updatedState);
          });
        },
        createEvent: (callback) => {
          Event.create({
            instructions: req.query.instructions,
          })
          .then((createdEvent) => {
            callback(null, createdEvent);
          });
        },
        createPublishing: (callback) => {
          Publishing.create({
            start_date: req.query.startDate,
            end_date: req.query.endDate,
          })
          .then((createdPublishing) => {
            callback(null, createdPublishing);
          });
        }
      }, (error, result) => {
        resolve(result);
      });
    });
  }

Как передать идентификаторы двух записей втретья модель?

1 Ответ

0 голосов
/ 25 мая 2018

Есть несколько проблем с вашей реализацией!Прежде всего, ваше обещание никогда не отвергается.

Несмотря на это, вам на самом деле не нужно создавать обещание или использовать асинхронную синхронизацию, также вы не хотите, чтобы они выполнялись параллельно: если для создания записи Publishing требуется информация о Event, затем вы захотите сначала создать событие, чтобы у вас было его id, ТО затем передайте его во вход для публикации.

Еще одна важная вещь, взгляните на этот фрагмент кода:

  .then((updateState) => {
    updateState.forEach((postState) => {
      postState.updateAttributes({ state: 2 });
    });
  })
  .then((updatedState) => {
    callback(null, updatedState);
  });

Внутри первого вы делаете несколько обновлений, которые являются обещаниями.Они будут отправлены, и вы никогда не получите их значения обратно.Позвольте мне объяснить:

Подумайте, нужно ли вам сделать только одно обновление.Это будет выглядеть так:

  .then((updateStates) => {
    return updateStates[0].updateAttributes({ state: 2 });
  })

Видите, мы возвращаем обещание (в данном случае обновление), поэтому следующий then будет вызван только после разрешения обновления.

Если мы сделаем это:

  .then((updateStates) => {
    updateStates[0].updateAttributes({ state: 2 });
  })

Оно отправит обновление (что занимает много времени), но поскольку вы его не вернули, оно пройдет и ничего не вернет.Проверьте это:

var promise1 = new Promise(function(resolve, reject) {
  setTimeout(function(){
    resolve('foo')
  }, 2);
});

var promise2 = new Promise(function(resolve, reject) {
  setTimeout(function(){
    resolve('foo2')
  }, 2);
});


promise1
  .then(function(result){
    promise2
  })
  .then(function(result){
    console.log(result) //will print undefined
  })

promise1
  .then(function(result){
    return promise2
  })
  .then(function(result){
    console.log(result) //will print foo2
  })

Итак, вы вызываете несколько обновлений без возврата их значений;если они потерпят неудачу, вы никогда не узнаете.

Еще одна вещь: если что-то пойдет не так, вы, вероятно, захотите откатить все изменения, сделанные до сих пор, для этого вам следует использовать транзакции.

Может быть, вы должны попробовать что-то вроде этого (не проверено):

return Post.sequelize.transaction(function (t) {

    Post.findAll({
      where: { id: req.query.post_id },
      attributes: ['id', 'state']
    })
    .then((updatedStates) => {
      var promises = []
      updatedStates.forEach((postState) => {
        promises.push(postState.updateAttributes({ state: 2 },  {transaction: t}));
      });
      return Promise.all(promises);
    })
    .then((results) => {
      return Event.create({
        instructions: req.query.instructions,
      }, {transaction: t})
    })
    .then((createdEvent) => {
      return Publishing.create({
        post_id: req.query.post_id,
        event_id: createdEvent.id, //or event_id, depends on your model
        start_date: req.query.startDate,
        end_date: req.query.endDate,
      }, {transaction: t})
    });

}).then(function (result) {
  // Transaction has been committed
  // result is whatever the result of the promise chain returned to the transaction callback
}).catch(function (err) {
  // Transaction has been rolled back
  // err is whatever rejected the promise chain returned to the transaction callback
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...