更新:我已经进一步发展了。请看帖子的底部......
我正在开发一个基于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
,以便服务器可以创建任务记录。
不幸的是,我似乎无法获得创建的记录。我已经经历了多次迭代,而且我正处于一个看似合理的例外的地步 - 我只是难以理解“合理”的事情是......
例外:
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); }
});
};
我确信我错过了一些明显的东西,但我发现的文档对于这样的场景非常清楚。我很感激任何指导;我刚刚进入续集状态,我觉得有时候我可能咬得比我咀嚼更多......:)
更新:在仔细研究SQL之后,我发现在尝试插入连接表(TaskGroupings)时会抛出异常。它试图为任务的主ID插入一个NULL,这通常不是一件好事。看看代码,我意识到我在保存记录之前尝试添加关联,让我没有PK。在task.addTaskGroups()
处理该问题后移动save()
。
但是,我也意识到我正在将一个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);
...
当我查看调试器时,我可以看到taskGroup
对象中的所有内容,但taskGroup.taskGroupID
将以undefined
的形式返回,所以我仍然会收到异常,因为我我没有通过协会另一方的PK。
有什么事情可以解决这个代码片段的问题吗?
答案 0 :(得分:2)
好的,通过更改服务器端控制器:
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没有被填充,但这超出了原始问题的范围......