我正在使用我的Backend Node.js,Express.js和Sequelize来连接数据库。 我有一个n:m任务和键之间的关系。
任务和密钥由我和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
});
}
我希望使用该请求发送用户选择的所有密钥的数组。
在后端,它应该为TaskKeys
添加一个条目,用于发送的每个DictKey的新任务。
例如
表格任务:
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所有数据,并且由于Table TaskKey而获得所有密钥。
我找不到一个解释这个问题的示例,我目前唯一的解决方案就是$http.post(taskkey)
的前端,表foreach
中的每个键都有一个TaskKey
。但是后来在Live System中会有超过1000个密钥,所以这不是一个可接受的解决方案。
对于后端有一个很好的解决方案吗?
EDIT1:
... 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并没有多大帮助,因为没有示例或详细说明。 我尝试了几件事:
在我的后端,我没有TaskKeys的任何函数只用于任务和键。但据我所知,我不需要任何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'});
创建中间表,任务和密钥之间存在关联。所以通常add / create应该正常工作,它应该在TaskKeys中添加实例。
export function create(req, res) {
return Task.create(req.body.task)
.then(function(task){
return task.addTaskKeys(req.body.keys);//throws 500error
使用task.addTaskKeys添加与刚刚创建的Task =>的关联task_id
使用req.body.keys为他提供Keys => key_id
如果我将示例从Doc更改为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(项目,{状态:'已启动'}) 默认情况下,代码会将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]
})
没有错误但只创建任务而不是TaskKeys .... 那么整个时间我做错了什么?
EDIT2: 对于测试,我在MsSql中由Myself在Table TaskKeys中插入了数据。 使用SqlQuery
的TaskKey / Self Created DatasTaskID | 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));
}
ConsoleOutput:
[Object]
Object
_id:2 // the searched TaskId= 2 => right
dict_Keys:Array[2] // the Dependant 2 KeyIds => right
因此创建的表工作正常。 问题现在只是为什么通过Backend添加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与Task无关 那么这意味着他们没有连接在一起? 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添加/ set / get / create DictKey。
但是
命名策略
默认情况下,sequelize将使用模型名称(传递给的名称) sequelize.define)用于确定模型的名称 关联。
表示它按表格模型的名称添加函数define('dict_Keys'...
所以将add / set / get / Dict_Key添加到Task。
这是问题,因为我使用addDictkey而不是addDict_Key。
我希望它能帮助未来的其他人
答案 0 :(得分:2)
前端:要从前端获取数据,只需将数组包含为您发布的data
的属性。您可能还希望将任务特定属性包装在它们自己的对象中:
this.$http.post('/api/tasks', {
task: {
user_id: $scope.selectUser,
lang_id: $scope.selectLang,
name: $scope.newTask
},
keys: [ 2, 5, 6 ]
});
后端:Sequelize和其他ORM会尝试为您提供使用您定义的关系的工具。使用它们。您已经在使用belongsToMany,因此您只需要执行下一步,即使用创建的Task
对象在m:n
中创建TaskKeys
条目:
...
return Task.create(req.body.task)
.then(function(task) {
return task.addProjects(req.body.keys);
})
.then(respondWithResult(res, 201))
.catch(handleError(res));
...
至于使用密钥获取任务,只需使用include
选项:
...
return Task.findById(req.params.id, {
include: [ { model: db.DictKey } ]
})
...
答案 1 :(得分:0)
foreignKey
在关系的两边应该相同,设置另一个关键字使用otherKey
选项。