最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Node.jsSequelize.jsExpress.js - How to insert into many-to-many association? (syncasync?) - Stack Overflow

programmeradmin7浏览0评论

I have two models (Individual, Email) and am trying to insert into the created 'Individual_Email' table using the Sequelize mands. 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?

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."

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.

Sequelize Documentation: /

Code:

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: "[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

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!

I have two models (Individual, Email) and am trying to insert into the created 'Individual_Email' table using the Sequelize mands. 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?

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."

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.

Sequelize Documentation: http://docs.sequelizejs./en/latest/docs/associations/

Code:

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: "[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

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!

Share Improve this question asked Mar 7, 2015 at 23:00 smilehamsmileham 1,4602 gold badges18 silver badges29 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 10

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.

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 returning the promises for better chaining and error handling, but it's a start. I'd remend Bluebird's documentation on the matter (that's the Promise library that Sequelize uses, but there are several others)

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");
});

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.

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);
        });
});
发布评论

评论列表(0)

  1. 暂无评论