angularjs - 使用 Sequelize、NodeJS 和 AngularJS 创建 n 为 :m relationship, 的记录

标签 angularjs node.js sequelize.js

更新:我已经取得了相当大的进展。请参阅帖子底部...

我正在开发一个基于 sql-fullstack yeoman 生成器的项目,并且一直使用包含的示例代码作为指南。大多数情况下,事情进展顺利,但我现在遇到的情况是,我有两个具有双向 n:m 关系的表/模型:

任务组:

module.exports = function(sequelize, DataTypes) {
  var TaskGroup = sequelize.define("TaskGroup", {
    taskGroupID: {
      field: "TaskGroupID",
      type: DataTypes.INTEGER,
      allowNull: false,
      unique: true,
      autoIncrement: true,
      primaryKey: true
    },
    name: {
      field: "Name",
      type: DataTypes.STRING,
      allowNull: false
    },
    description: {
      field: "Description",
      type: DataTypes.STRING
    },
    modifiedBy: {
      field: "ModifiedBy",
      type: DataTypes.STRING
    }
  });

和任务:

module.exports = function(sequelize, DataTypes) {
  var Task = sequelize.define("Task", {
    taskID: {
      field: "TaskID",
      type: DataTypes.INTEGER,
      allowNull: false,
      unique: true,
      autoIncrement: true,
      primaryKey: true
    },
    name: {
      field: "Name",
      type: DataTypes.STRING,
      allowNull: false
    },
    description: {
      field: "Description",
      type: DataTypes.STRING
    },
    isOnRunsheet: {
      field: "IsOnRunsheet",
      type: DataTypes.BOOLEAN
    },
    modifiedBy: {
      field: "ModifiedBy",
      type: DataTypes.STRING
    }
  });

关系:

  // Tasks can belong to more than one group, and groups can belong to more than one task
  db['TaskGroup'].belongsToMany(db['Task'], {as: 'Tasks', through: 'TaskGrouping'});
  db['Task'].belongsToMany(db['TaskGroup'], {as: 'TaskGroups', through: 'TaskGrouping'});

在客户端,用户可以创建新任务并通过多选列表指定关联的任务组。保存任务时,我拥有任务字段和关联任务组的数组。使用包含此信息的请求正文进行 post,以便服务器可以创建任务记录。

不幸的是,我似乎无法创建记录。我已经经历了多次迭代,现在我得到了一个看似合理的异常(exception) - 我只是对“合理”的做法感到困惑......

异常(exception):

Unhandled rejection SequelizeDatabaseError: Cannot insert the value NULL into column 'TaskTaskID', table 'HelpCard
.dbo.TaskGrouping'; column does not allow nulls. INSERT fails.
    at Query.formatError (C:\Projects\helpcard2\node_modules\sequelize\lib\dialects\mssql\query.js:215:10)
    at Request.userCallback (C:\Projects\helpcard2\node_modules\sequelize\lib\dialects\mssql\query.js:66:25)
    at Request.callback (C:\Projects\node_modules\tedious\lib\request.js:33:27)
    at Connection.message (C:\Projects\node_modules\tedious\lib\connection.js:1179:27)
    at Connection.dispatchEvent (C:\Projects\node_modules\tedious\lib\connection.js:519:45)
    at MessageIO.<anonymous> (C:\Projects\node_modules\tedious\lib\connection.js:439:23)
    at emitNone (events.js:67:13)
    at MessageIO.emit (events.js:166:7)
    at ReadablePacketStream.<anonymous> (C:\Projects\node_modules\tedious\lib\message-io.js:92:15)
    at emitOne (events.js:77:13)
...

这是客户端的代码:

$scope.createTask = function() {
  if($scope.newTask === '') {
    return;
  }
  $scope.newTask.modifiedBy = 'tkturney';
  var taskBundle = {
      task: $scope.newTask,
      taskGroups: $scope.selectedGroups
  };
  $http.post('/api/tasks', taskBundle);
  setTimeout(function() {
    $scope.currentTask = $scope.newTask;
    $scope.newTask = '';
    $scope.addingTask = false;
    refreshTasks();
  }, 250);
};

...在服务器端:

exports.create = function(req, res) {
  var task = Task(req).build(req.body.task);
  task.setTaskGroups(req.body.taskGroups);
  task
    .save()
    .then(function() {
      return res.status(201).json(task);
    })
    .catch(function (err){
      if(err) { return handleError(res, err); }
    });
};

我确信我遗漏了一些明显的东西,但是我找到的文档对于这样的场景来说非常简单。我将不胜感激任何指导;我刚刚开始写 Sequelize ,我觉得有些时候我可能已经贪多嚼不烂了……:)

更新:仔细查看 SQL 后,我发现尝试插入连接表(TaskGroupings)时抛出异常。它试图为任务的主 ID 插入 NULL,这通常不是一件好事。查看代码,我意识到我试图在保存记录之前添加关联,从而使我没有PK。在 save() 之后移动 task.addTaskGroups() 解决了这个问题。

但是,我还意识到我正在将 TaskGroup 对象数组传递给“addTaskGroup()”调用,而不是实际的 ID。因此,我修改了客户端 Controller ,如下所示:

$scope.createTask = function() {
  if($scope.newTask === '') {
    return;
  }
  $scope.groupKeys = [];
  angular.forEach($scope.selectedGroups, function(taskGroup) {
    $scope.groupKeys.push(taskGroup.taskGroupID);
  });
  $scope.newTask.modifiedBy = 'tkturney';
  var taskBundle = {
      task: $scope.newTask,
      taskGroups: $scope.groupKeys
  };
  $http.post('/api/tasks', taskBundle);
  ...

当我查看调试器时,我可以看到 taskGroup 对象中的所有内容,但 taskGroup.taskGroupID 返回为 undefined,所以我仍然遇到异常,因为我没有传递关联另一方的 PK。

这段代码片段有什么问题吗?

最佳答案

好的,通过更改服务器端 Controller :

exports.create = function(req, res) {
  var task = Task(req).build(req.body.task);
  task.setTaskGroups(req.body.taskGroups);
  task
    .save()
    .then(function() {
      return res.status(201).json(task);
    })
    .catch(function (err){
      if(err) { return handleError(res, err); }
    });
};

对此:

exports.create = function(req, res) {
  var task = Task(req).build(req.body.task);
  task
    .save()
    .then(function() {
      task.setTaskGroups(req.body.taskGroups);
      return res.status(201).json(task);
    })
    .catch(function (err){
      if(err) { return handleError(res, err); }
    });
};

那个特殊的异常消失了。我错过的一件事(尽管它就在我面前)是有两个单独的插入发生的事实 - 一个用于任务,另一个用于关联。我认为我需要在保存任务之前设置关联,但没有意识到设置该关联会导致另一次插入。

我仍然需要弄清楚为什么关联另一方的 PK 没有被填充,但这超出了原始问题的范围......

关于angularjs - 使用 Sequelize、NodeJS 和 AngularJS 创建 n 为 :m relationship, 的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37994849/

相关文章:

javascript - 我怎样才能显示第一个项目,在 angularjs 上切换就绪

javascript - promise 首先执行特定代码

javascript - AngularJs 更新 Bootstrap 进度条

angularjs - 使用 Jasmine 测试 AngularJS 的 .then() 返回值

node.js - 对 Sequelize 关联感到困惑

node.js - 如何设置带环回的 redis 快速 session 存储?

node.js - Sequelize 列 Table.createdAt 不存在

node.js - Sequelize中如何使用CASE WHEN表达式?

node.js - 根据事务 Sequelize hook

javascript - 如何使用nodeJS和Puppeteer解决 "Target closed"错误?