1

我正在使用 node.js 开发应用程序并表达 REST API 来管理 sqlite 数据库后端。我正在使用 sequelize 作为 orm。到目前为止一切正常,但我发现了一个我无法解决的奇怪错误。我有一个处理基本游戏设置的游戏端点,例如它是哪个游戏以及游戏的哪个变体以及一个标志,如果游戏获胜或需要下一个玩家执行操作。

所以 this won 和 nextPlayerNeeded 就像你已经可以猜到布尔标志一样。我的模型如下所示:

模型/game.js

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Game = sequelize.define(
    'Game',
    {
      game: DataTypes.STRING,
      variant: DataTypes.STRING,
      inGame: DataTypes.STRING,
      outGame: DataTypes.STRING,
      won: DataTypes.BOOLEAN,
      nextPlayerNeeded: DataTypes.BOOLEAN
    },
    {}
  );
  Game.associate = function(models) {};
  return Game;
};

相应的迁移脚本是,

迁移/game.js

'use strict';
module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Games', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      game: {
        allowNull: false,
        type: Sequelize.STRING
      },
      variant: {
        allowNull: false,
        type: Sequelize.STRING
      },
      inGame: {
        allowNull: true,
        type: Sequelize.STRING
      },
      outGame: {
        allowNull: true,
        type: Sequelize.STRING
      },
      won: {
        allowNull: false,
        type: Sequelize.BOOLEAN
      },
      nextPlayerNeeded: {
        allowNull: false,
        type: Sequelize.BOOLEAN
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Games');
  }
};

我的 CRUD 控制器controller/gameController.js看起来像这样:

const { Game } = require('../models');
const fs = require('fs');

module.exports = {
  getAllGames(req, res) {
    return Game.findAll({
      attributes: [
        'id',
        'game',
        'variant',
        'inGame',
        'outGame',
        'won',
        'nextPlayerNeeded'
      ]
    })
      .then(games => res.status(200).send(games))
      .catch(err => res.status(400).send(err));
  },
  getSpecificGame(req, res) {
    return Game.findByPk(req.params.id, {
      attributes: [
        'id',
        'game',
        'variant',
        'inGame',
        'outGame',
        'won',
        'nextPlayerNeeded'
      ]
    }).then(game => {
      if (!game) {
        return res.status(404).send({
          message: `Game with id ${req.params.id} not found`
        });
      }
      return res.status(200).send(game);
    });
  },
  createGame(req, res) {
    return Game.create({
      game: req.body.game,
      variant: req.body.variant,
      inGame: req.body.inGame,
      outGame: req.body.outGame,
      won: false,
      nextPlayerNeeded: false
    })
      .then(game => res.status(201).json(game))
      .catch(err => res.status(400).send(err));
  },
  updateGame(req, res) {
    return Game.findByPk(req.params.id, {
      attributes: [
        'id',
        'game',
        'variant',
        'inGame',
        'outGame',
        'won',
        'nextPlayerNeeded'
      ]
    })
      .then(game => {
        if (!game) {
          return res.status(404).send({
            message: `Game with id ${req.params.id} not found`
          });
        }
        return game
          .update({
            game: req.body.game || game.game,
            variant: req.body.variant || game.variant,
            inGame: req.body.inGame || game.inGame,
            outGame: req.body.outGame || game.outGame,
            won: req.body.won || game.won,
            nextPlayerNeeded: req.body.nextPlayerNeeded || game.nextPlayerNeeded
          })
          .then(() => res.status(200).send(game))
          .catch(err => res.status(400).send(err));
      })
      .catch(err => res.status(400).send(err));
  },
  deleteGame(req, res) {
    return Game.findByPk(req.params.id, {
      attributes: [
        'id',
        'game',
        'variant',
        'inGame',
        'outGame',
        'won',
        'nextPlayerNeeded'
      ]
    })
      .then(game => {
        if (!game) {
          return res.status(404).send({
            message: `Game with id ${req.params.id} not found`
          });
        }
        return game
          .destroy()
          .then(() => res.status(204).send())
          .catch(err => res.status(400).send(err));
      })
      .catch(err => res.status(400).send(err));
  }
};

有趣的来了。我正在使用 insomnia 作为测试客户端,我可以更新实例化的游戏对象,说它赢了(真)并且它有 nextPlayerNeeded(真)。因此,虽然获胜不应该再次更新为 false,因为如果获胜则游戏结束,在切换到下一个玩家后,标志 nextPlayerNeeded 应该再次为 false。但是将它们中的任何一个更新为 true 都无法再次更新为 false。这是为什么?为什么我只能将这些更新为字段一次?

例如,这是我将标志更新为 true 的请求的响应:

{
  "id": 2,
  "game": "X01",
  "variant": "301",
  "inGame": "Straight",
  "outGame": "Double",
  "won": false,
  "nextPlayerNeeded": true,
  "updatedAt": "2020-01-21T10:47:23.767Z"
}

我可以随心所欲地更新所有字符串标志,但不能更新布尔标志。

如果我能得到任何提示,我将不胜感激。谢谢

4

1 回答 1

0

我确实重构了我的项目以使用 GraphQL Apollo 服务器和客户端而不是 REST Api。尽管在这两种变体中我都使用了 GraphQL 的 sequelize,但它确实会根据需要对其进行多次更新。所以考虑一下这个没有答案但已经关闭的问题。

于 2020-01-24T18:27:48.547 回答