javascript Node.js / Sequelize.js / Express.js - 如何插入多对多关联?(同步/异步?)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28921074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node.js / Sequelize.js / Express.js - How to insert into many-to-many association? (sync/async?)
提问by smileham
I have two models (Individual, Email) and am trying to insert into the created 'Individual_Email' table using the Sequelize commands. While Sequelize is creating the desired table, it returns the following error when trying to add/get/set to/from that table: "Object [object Promise] has no method 'addEmail'". What am I missing?
我有两个模型(个人、电子邮件),并且正在尝试使用 Sequelize 命令插入到创建的“Individual_Email”表中。当 Sequelize 创建所需的表时,它在尝试向/从该表添加/获取/设置时返回以下错误:“对象 [对象承诺] 没有方法‘addEmail’”。我错过了什么?
The Sequelize documentation says if the models are User and Project, "This will add methods getUsers, setUsers, addUsers to Project, and getProjects, setProjects and addProject to User."
Sequelize 文档说,如果模型是 User 和 Project,“这会将方法 getUsers、setUsers、addUsers 添加到 Project,并将 getProjects、setProjects 和 addProject 添加到 User。”
This leads me to believe (looking at promises) that I'm likely misunderstanding how to use the asynchronous features of Node. I've tried both a synchronous and async version of insertion, both returning the same message above.
这让我相信(查看 promise)我可能误解了如何使用 Node.js 的异步功能。我已经尝试了同步和异步版本的插入,都返回了上面相同的消息。
Sequelize Documentation: http://docs.sequelizejs.com/en/latest/docs/associations/
续集文档:http://docs.sequelizejs.com/en/latest/docs/associations/
Code:
代码:
routes/index.js
路线/ index.js
var express = require('express');
var router = express.Router();
var models = require('../models');
/* GET home page. */
router.get('/', function(req, res, next) {
'use strict';
var tIndividual, tEmail;
tIndividual = models.Individual.create({
name: "Test"
});
tEmail = models.Email.create({
address: "[email protected]"
});
console.log(tEmail);
res.render('index', { title: 'Express' });
});
module.exports = router;
OR
或者
/* GET home page. */
router.get('/', function(req, res, next) {
'use strict';
var tIndividual, tEmail;
tIndividual = models.Individual.create({
name: "Test"
}).then(function(){
tEmail = models.Email.create({
address: "[email protected]"
}).then(function(){
tIndividual.addEmail(tEmail).then(function(){
console.log("Success");
});
})
});
res.render('index', { title: 'Express' });
});
module.exports = router;
models/index.js
模型/index.js
db.Individual.hasMany(db.Email, {
as: 'Email',
through: 'Individual_Email'
});
db.Email.hasMany(db.Individual, {
as: 'Individual',
through: 'Individual_Email'
});
How can I add to the table 'Individual_Email' in the best way? I'm assuming I need to do it synchronously to wait for the update, but I'm open to any suggestions. Thanks!
如何以最佳方式将“Individual_Email”添加到表中?我假设我需要同步进行以等待更新,但我愿意接受任何建议。谢谢!
回答by st.never
When you call .save()
or .create()
or other methods that return a Promise, you should call .then()
on that promise. When it resolves -- that is, when the object gets saved/created/something-elsed -- your then
function will be called, and will receive the saved/created object as a parameter.
当您调用.save()
or.create()
或其他返回 Promise 的方法时,您应该调用该 Promise .then()
。当它解析时——也就是说,当对象被保存/创建/其他东西时——你的then
函数将被调用,并将接收保存/创建的对象作为参数。
So your first attempt could be rewritten as:
所以你的第一次尝试可以改写为:
models.Individual.create({
name: "Test"
}).then(function(createdIndividual) { // note the argument
models.Email.create({
address: "[email protected]"
}).then(function(createdEmail) { // note the argument
createdIndividual.addEmail(createdEmail)
.then(function(addedEmail) { // note th-- well you get the idea :)
console.log("Success");
});
})
});
The above code lacks a few important things, such as return
ing the promises for better chaining and error handling, but it's a start. I'd recommend Bluebird's documentationon the matter (that's the Promise library that Sequelize uses, but there are several others)
上面的代码缺少一些重要的东西,例如return
为了更好的链接和错误处理而使用 promise,但这是一个开始。我会推荐Bluebird关于此事的文档(这是 Sequelize 使用的 Promise 库,但还有其他几个)
回答by jdnichollsc
You can mitigate the "Pyramid of Doom" using promises of the best way:
您可以使用最佳方式的承诺来缓解“末日金字塔”:
var createdIndividual;
models.Individual.create({
name: "Test"
}).then(function(createdIn) { // note the argument
createdIndividual = createdIn;
return models.Email.create({
address: "[email protected]"
});
}).then(function(createdEmail) { // note the argument
return createdIndividual.addEmail(createdEmail);
}).then(function(addedEmail) { // note th-- well you get the idea :)
console.log("Success");
});
回答by smileham
I figured out how to solve it in one way, but let me know if there's a better way.
我想出了如何以一种方式解决它,但如果有更好的方法,请告诉我。
My solution: Since .create() returned a promise, I instead used .build() which returned an instance, and only added to 'Individual_Email' after both had been saved synchronously. I then called the add method on the instance returned from .build() and inserted into the table.
我的解决方案:由于 .create() 返回了一个承诺,我改为使用 .build() 返回一个实例,并且仅在两者同步保存后才添加到“Individual_Email”。然后我在从 .build() 返回的实例上调用 add 方法并插入到表中。
My code:
我的代码:
var tIndividual, tEmail;
tIndividual = models.Individual.build({
name: "Test"
});
tEmail = models.Email.build({
address: '[email protected]'
});
tIndividual.save()
.success(function(){
tEmail.save()
.success(function(){
tIndividual.addEmail(tEmail);
});
});