Node.js / Sequelize.js / Express.js - 如何插入多对多关联? (sync/async?)
Node.js / Sequelize.js / Express.js - How to insert into many-to-many association? (sync/async?)
我有两个模型(个人模型、电子邮件模型),我正在尝试使用 Sequelize 命令插入到创建的 'Individual_Email' table 中。当 Sequelize 正在创建所需的 table 时,它 returns 在尝试 add/get/set to/from that table: "Object [object Promise] has no method 'addEmail'" 时出现以下错误。我错过了什么?
Sequelize 文档说如果模型是用户和项目,"This will add methods getUsers, setUsers, addUsers to Project, and getProjects, setProjects and addProject to User."
这让我相信(查看 promises)我可能误解了如何使用 Node.js 的异步功能。我已经尝试了插入的同步和异步版本,都返回了上面相同的消息。
续集文档:http://docs.sequelizejs.com/en/latest/docs/associations/
代码:
routes/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: "test@gmail.com"
});
console.log(tEmail);
res.render('index', { title: 'Express' });
});
module.exports = router;
或
/* 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: "test@gmail.com"
}).then(function(){
tIndividual.addEmail(tEmail).then(function(){
console.log("Success");
});
})
});
res.render('index', { title: 'Express' });
});
module.exports = router;
models/index.js
db.Individual.hasMany(db.Email, {
as: 'Email',
through: 'Individual_Email'
});
db.Email.hasMany(db.Individual, {
as: 'Individual',
through: 'Individual_Email'
});
如何以最佳方式添加到 table 'Individual_Email'?我假设我需要同步进行以等待更新,但我愿意接受任何建议。谢谢!
我找到了一种解决方法,但如果有更好的方法请告诉我。
我的解决方案:
由于 .create() 返回了一个承诺,我改为使用 .build() 返回一个实例,并且仅在两者同步保存后才添加到 'Individual_Email' 。然后我在从 .build() 返回的实例上调用了 add 方法并插入到 table.
我的代码:
var tIndividual, tEmail;
tIndividual = models.Individual.build({
name: "Test"
});
tEmail = models.Email.build({
address: 'test@gmail.com'
});
tIndividual.save()
.success(function(){
tEmail.save()
.success(function(){
tIndividual.addEmail(tEmail);
});
});
当您调用 .save()
或 .create()
或 return Promise 的其他方法时,您应该对该 Promise 调用 .then()
。当它解析时——也就是说,当对象获得 saved/created/something-elsed 时——你的 then
函数将被调用,并将接收 saved/created 对象作为参数。
因此您的第一次尝试可以重写为:
models.Individual.create({
name: "Test"
}).then(function(createdIndividual) { // note the argument
models.Email.create({
address: "test@gmail.com"
}).then(function(createdEmail) { // note the argument
createdIndividual.addEmail(createdEmail)
.then(function(addedEmail) { // note th-- well you get the idea :)
console.log("Success");
});
})
});
上面的代码缺少一些重要的东西,例如 return
为了更好的链接和错误处理而承诺,但这只是一个开始。我建议 Bluebird's documentation 解决这个问题(这是 Sequelize 使用的 Promise 库,但还有其他几个库)
您可以使用最佳方式的承诺来缓解“Pyramid of Doom”:
var createdIndividual;
models.Individual.create({
name: "Test"
}).then(function(createdIn) { // note the argument
createdIndividual = createdIn;
return models.Email.create({
address: "test@gmail.com"
});
}).then(function(createdEmail) { // note the argument
return createdIndividual.addEmail(createdEmail);
}).then(function(addedEmail) { // note th-- well you get the idea :)
console.log("Success");
});
我有两个模型(个人模型、电子邮件模型),我正在尝试使用 Sequelize 命令插入到创建的 'Individual_Email' table 中。当 Sequelize 正在创建所需的 table 时,它 returns 在尝试 add/get/set to/from that table: "Object [object Promise] has no method 'addEmail'" 时出现以下错误。我错过了什么?
Sequelize 文档说如果模型是用户和项目,"This will add methods getUsers, setUsers, addUsers to Project, and getProjects, setProjects and addProject to User."
这让我相信(查看 promises)我可能误解了如何使用 Node.js 的异步功能。我已经尝试了插入的同步和异步版本,都返回了上面相同的消息。
续集文档:http://docs.sequelizejs.com/en/latest/docs/associations/
代码:
routes/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: "test@gmail.com"
});
console.log(tEmail);
res.render('index', { title: 'Express' });
});
module.exports = router;
或
/* 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: "test@gmail.com"
}).then(function(){
tIndividual.addEmail(tEmail).then(function(){
console.log("Success");
});
})
});
res.render('index', { title: 'Express' });
});
module.exports = router;
models/index.js
db.Individual.hasMany(db.Email, {
as: 'Email',
through: 'Individual_Email'
});
db.Email.hasMany(db.Individual, {
as: 'Individual',
through: 'Individual_Email'
});
如何以最佳方式添加到 table 'Individual_Email'?我假设我需要同步进行以等待更新,但我愿意接受任何建议。谢谢!
我找到了一种解决方法,但如果有更好的方法请告诉我。
我的解决方案: 由于 .create() 返回了一个承诺,我改为使用 .build() 返回一个实例,并且仅在两者同步保存后才添加到 'Individual_Email' 。然后我在从 .build() 返回的实例上调用了 add 方法并插入到 table.
我的代码:
var tIndividual, tEmail;
tIndividual = models.Individual.build({
name: "Test"
});
tEmail = models.Email.build({
address: 'test@gmail.com'
});
tIndividual.save()
.success(function(){
tEmail.save()
.success(function(){
tIndividual.addEmail(tEmail);
});
});
当您调用 .save()
或 .create()
或 return Promise 的其他方法时,您应该对该 Promise 调用 .then()
。当它解析时——也就是说,当对象获得 saved/created/something-elsed 时——你的 then
函数将被调用,并将接收 saved/created 对象作为参数。
因此您的第一次尝试可以重写为:
models.Individual.create({
name: "Test"
}).then(function(createdIndividual) { // note the argument
models.Email.create({
address: "test@gmail.com"
}).then(function(createdEmail) { // note the argument
createdIndividual.addEmail(createdEmail)
.then(function(addedEmail) { // note th-- well you get the idea :)
console.log("Success");
});
})
});
上面的代码缺少一些重要的东西,例如 return
为了更好的链接和错误处理而承诺,但这只是一个开始。我建议 Bluebird's documentation 解决这个问题(这是 Sequelize 使用的 Promise 库,但还有其他几个库)
您可以使用最佳方式的承诺来缓解“Pyramid of Doom”:
var createdIndividual;
models.Individual.create({
name: "Test"
}).then(function(createdIn) { // note the argument
createdIndividual = createdIn;
return models.Email.create({
address: "test@gmail.com"
});
}).then(function(createdEmail) { // note the argument
return createdIndividual.addEmail(createdEmail);
}).then(function(addedEmail) { // note th-- well you get the idea :)
console.log("Success");
});