更新:我已经取得了相当大的进展。请参阅帖子底部...
我正在开发一个基于 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/