【发布时间】:2016-12-12 00:23:41
【问题描述】:
我正在使用我的后端 Node.js、Express.js 和 Sequelize 来连接到数据库。 我在任务和键之间有一个 n:m 关系。
Tasks and Keys 是我和 TaskKey 通过 Sequelize 创建的:
后端
// Tasks n:m Keys
db.DictKey.belongsToMany(db.Task, { through: 'TaskKeys' , foreignKey:'key_id'});
db.Task.belongsToMany(db.DictKey, { through: 'TaskKeys' , foreignKey: 'task_id'});
现在如果我在
上创建一个新任务前端
$scope.create = () => {
this.$http.post('/api/tasks', {
user_id: $scope.selectUser,
lang_id: $scope.selectLang,
name: $scope.newTask
});
}
我想与该请求一起发送用户选择的所有键的数组。
在后端,它应该为发送的每个 DictKey 的新任务添加一个到 TaskKeys 的条目。
例如
表任务:
ID | some values
1 | some values | this is the new task created
在数组[2,5,6]中发送密钥
TaskKey / 同时在这个表中创建依赖键
TaskID | KeyID
1 | 2
1 | 5
1 | 6
我怎样才能做到这一点?
之后我想展示一个任务。 以之前的例子为例。 获取 id = 1 的任务 ng-repeat all data 并通过 Table TaskKey 获取所有 Key。
我找不到一个示例来解释这一点,而我目前唯一的解决方案是在前端使用$http.post(taskkey),表TaskKey 中的每个键都有foreach。但后来在 Live System 中会有超过 1000 个键,所以这不是一个可接受的解决方案。
后端有没有好的解决方案?
编辑1:
... working fine
$scope.create = () => {
this.$http.post('/api/tasks', {
task:{
user_id: $scope.selectUser,
lang_id: $scope.selectLang,
name: $scope.newTask
},
keys:[1,2,3,4,5]
});
...
...
// Creates a new Task in the DB
export function create(req, res) {
return Task.create(req.body.task)
.then(function(task){
return task.addTaskKeys(req.body.keys);//throws 500error
//console.log(req.body.keys);//working fine getting the Keys
})
.then(respondWithResult(res, 201))
.catch(handleError(res));
}
...
阅读文档belongsToManyDoc 并没有多大帮助,因为没有示例或详细说明。 我尝试了几件事,例如:
- addTask/addTasks/addTaskKeys/addKey 如文档中解释的添加关联
- createTask/createKey/createTaskKeys 用于创建关联
在我的后端,我没有任务键的任何功能,仅适用于任务和键。但据我了解,我不需要 TaskKeys,因为有了
// Tasks n:m Keys
db.DictKey.belongsToMany(db.Task, { through: 'TaskKeys' , foreignKey:'key_id'});
db.Task.belongsToMany(db.DictKey, { through: 'TaskKeys' , foreignKey: 'task_id'});
创建 Middle Table 存在 Tasks 和 Keys 之间的关联。所以通常添加/创建应该可以正常工作,它应该在 TaskKeys 中添加实例。
export function create(req, res) {
return Task.create(req.body.task)
.then(function(task){
return task.addTaskKeys(req.body.keys);//throws 500error
with task.addTaskKeys 添加与刚刚创建的 Task=> task_id 的关联
req.body.keys 给他 Keys =>key_id
如果我将示例从 Doc change 改为 minde DB:
... example
Project.create({ id: 11 }).then(function (project) {
user.addProjects([project, 12]);
});
... mine
return Task.create(req.body.task)
.then(function(task){
return DictKey.addTasks([task,{key_id : 1}]);//still error
})//DictKey.addTask(task,1); still error
阅读 BelongsToMany 关联并引用它:
user.addProject(project, { status: 'started' }) 默认情况下,代码会将 projectId 和 userId 添加到 UserProjects 表中
尝试使用关联创建:
http://sequelize.readthedocs.io/en/latest/docs/associations/#creating-elements-of-a-hasmany-or-belongstomany-association 抱歉,不允许以 1 个链接的形式发布更多内容。
export function create(req, res) {
return Task.create({
name: req.body.task.name,
user_id: req.body.task.user_id,
lang_id: req.body.task.lang_id,
key_id:[req.body.keys]
},{
include: [DictKey]
})
没有错误,但只创建任务而不是任务键...... 那么我一直在做错什么?
编辑2: 为了测试,我自己在 MsSql 中的 Table TaskKeys 中插入了数据。 TaskKey / 使用 SqlQuery 自行创建的数据
TaskID | KeyID
1 | 1
1 | 2
1 | 3
2 | 4
2 | 5
从我的前端获取它
this.$http.get('/api/tasks/' +2 )
.then(response => {
this.Tasks = response.data;
console.log(this.Tasks);
});
后端
// Gets a single Task from the DB
export function show(req, res) {
return Task.findAll({
where: {
_id: req.params.id
},
include: [{
model: DictKey
}]
})
.then(handleEntityNotFound(res))
.then(respondWithResult(res))
.catch(handleError(res));
}
控制台输出:
[Object]
Object
_id:2 // the searched TaskId= 2 => right
dict_Keys:Array[2] // the Dependant 2 KeyIds => right
所以创建的表工作正常。 现在的问题只是为什么通过与示例中的相同操作无法使用 addKey 通过后端添加。 尝试检查关联的示例:
// Creates a new Task in the DB
export function create(req, res) {
Task.create({
name: req.body.task.name,
user_id: req.body.task.user_id,
lang_id: req.body.task.lang_id
}).then(function(task) {
return DictKey.create({ name:req.body.task.name,notice:req.body.task.name, user_id:req.body.task.user_id })
.then(function(key) {
return task.hasDictKey(key).then(function(result) {
// result would be false
return task.addDictKey(key).then(function() {
return task.hasDictKey(key).then(function(result) {
// result would be true
})
})
})
})
})
抛出 task.hasDictKey 不是函数
db.Task.create({
name: 'test',
user_id: 266,
lang_id: 9,
key_id:[1,2]
},{
include: [db.DictKey]
})
抛出 dict_Keys 未关联到任务 所以这意味着它们没有连接在一起? BUt 在数据库中读取数据和插入数据是否有效?
现在只添加 Sequelize 的例子:
var Usert = db.sequelize.define('usert', {})
var Project = db.sequelize.define('project', {})
var UserProjects = db.sequelize.define('userProjects', {
status: Sequelize.STRING
})
Usert.belongsToMany(Project, { through: UserProjects })
Project.belongsToMany(Usert, { through: UserProjects })
Usert.addProject(Project, { status: 'started' })//addProject is not a Function // for real ? now not even their own is not working? :/
回答
通过阅读我想到的文档
// Tasks n:m Keys
db.DictKey.belongsToMany(db.Task, { through: TaskKeys , foreignKey:'key_id',otherKey:'task_id'});
db.Task.belongsToMany(db.DictKey, { through: TaskKeys , foreignKey: 'task_id',otherKey: 'key_id'});
它会自动为 DictKey 生成 add/set/get/create Task 并为 Task 生成 add/set/get/create DictKey。
但是
命名策略
默认情况下,sequelize 将使用模型名称(传递给 sequelize.define) 来确定模型在使用时的名称 协会。
意味着它通过您所在的表模型的名称添加函数define('dict_Keys'...
所以添加/设置/获取/ Dict_Key 到任务。
这就是问题所在,因为我使用的是 addDictkey 而不是 addDict_Key。
我希望它可以帮助未来的其他人
【问题讨论】:
标签: angularjs sql-server node.js express sequelize.js