使用Sequelize,NodeJS和AngularJS创build具有n:m关系的logging

更新 :我已经进一步了。 请看post的底部

我正在开发一个基于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'}); 

在客户端,用户可以创build一个新的任务,并通过一个多选列表指定相关的任务组。 当任务被保存时,我有两个任务域和一个相关的任务组的数组。 包含此信息的请求主体post了一个post ,以便服务器可以创build任务logging。

不幸的是,我似乎无法获得创build的logging。 我已经经历了许多次迭代,而且我正处在一个看似合理的例外的地步 – 我只是不知道要做什么“合理”的事情。

例外:

 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)时引发exception。 它试图为任务的主ID插入一个NULL,这通常不是一件好事。 看着代码,我意识到我正在试图添加关联,然后我保存了logging,没有PK。 在task.addTaskGroups()处理完这个问题之后,移动task.addTaskGroups()

然而,我也意识到我传递了一个TaskGroup对象的数组到'addTaskGroup()`调用,而不是实际的ID。 所以,我修改了客户端控制器,如下所示:

 $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); ... 

当我查看debugging器时,我可以看到taskGroup对象中的所有内容,但是taskGroup.taskGroupID返回的是undefined ,所以我仍然得到一个exception,因为我没有通过关联的另一端的PK。

有什么东西可以跳出来,这个代码片段可能是什么东西?

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

 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); } }); }; 

这个特殊的例外消失了。 我错过的东西(尽pipe它正在盯着我)是有两个单独的插入发生的事实 – 一个用于任务,一个用于关联。 我以为我需要在保存任务之前设置关联,而不是意识到设置该关联会导致另一个插入。

我仍然需要弄清楚为什么协会另一方的PK没有得到满足,但这超出了原始问题的范围。