使用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没有得到满足,但这超出了原始问题的范围。
- 在Javascript中实现时间间隔树
- CORS无法在Firefox中运行
- 使用Angularfire,Passport和Express / Nodejspipe理会话
- 请求的资源上没有“Access-Control-Allow-Origin”标题。 NodeJS和AngularJS应用程序
- 将Web服务隐藏到NodeJS中的外行用户
- Angular $ http.get和Express req.body是空的
- 需要使用Browserify的控制器,工厂,服务和指令文件
- 在MEAN堆栈中应该创buildvalidation规则的地方?
- 阻止使用AngularJs和Node.js / Express直接访问文件