Sequelize associations:set[Models]添加新模型,而不是关联现有模型

Sequelize associations: set[Models] adds new models instead of associating existing ones

本文关键字:模型 关联 set associations Models 新模型 添加 Sequelize      更新时间:2023-09-26

我正在使用Sequelize,并试图在两个不同的表之间创建关联,其中x.belongsTo(y)y.hasMany(x)。在完成x.setY(yInstance)y.getXs()之后,似乎只向x添加了新行,并且没有创建与我已经创建的实例的关联。

var Promise = require("bluebird"),
    Sequelize = require("sequelize");
var sequelize = new Sequelize("Test", "postgres", "password", {
    host: "localhost",
    dialect: "postgres",
    pool: {
        max: 5,
        min: 0,
        idle: 10000
    }
});
var Schedule = sequelize.define("Schedule", {
    website: {
        type: Sequelize.STRING
    }
});
var SiteConfig = sequelize.define("SiteConfig", {
    systemType: {
        type: Sequelize.STRING
    }
});
var Selector = sequelize.define("Selector", {
    type: {
        type: Sequelize.STRING
    },
    content: {
        type: Sequelize.STRING
    }
});
Selector.belongsTo(SiteConfig);
SiteConfig.hasMany(Selector);
var testSchedule = {
    website: "google.com"
};
var testSiteConfig = {
    systemType: "one"
};
var testSelectors = [
    {type: "foo", content: "foo"},
    {type: "foo", content: "bar"}
];

Promise.all([
    Schedule.sync({force: true}),
    SiteConfig.sync({force: true}),
    Selector.sync({force: true})
]).then(function () {
    return Promise.all([
        Schedule.create(testSchedule),
        SiteConfig.create(testSiteConfig),
        Selector.bulkCreate(testSelectors)
    ]);
}).spread(function (schedule, siteConfig, selectors) {
    return Promise.map(selectors, function (selector) {
        return selector.setSiteConfig(siteConfig);
    }).then(function (array) {
        return siteConfig.getSelectors();
    }).each(function (selector) {
        // This is where I expect "foo" and "bar" but instead get null
        console.log("Selector content:", selector.get("content"));
    });
});

我希望这段代码能在Selectors中添加一个SiteConfigId列,这样我的siteConfig.getSelectors()就会返回我的testSelectors。我怎样才能做到这一点?

[UPDATE]

事实证明我之前所做的是错误的。方法setSiteConfig()不是您想要使用的。我检查了数据库,看起来Sequelize创建了两个新记录,而不是关联现有的foo/bar选择器:

test=# select * from "Selectors";
 id | type | content |         createdAt          |         updatedAt          | SiteConfigId 
----+------+---------+----------------------------+----------------------------+--------------
  1 | foo  | foo     | 2015-04-05 20:38:55.282-07 | 2015-04-05 20:38:55.282-07 |             
  2 | foo  | bar     | 2015-04-05 20:38:55.282-07 | 2015-04-05 20:38:55.282-07 |             
  3 |      |         | 2015-04-05 20:38:55.282-07 | 2015-04-05 20:38:55.311-07 |            1
  4 |      |         | 2015-04-05 20:38:55.282-07 | 2015-04-05 20:38:55.31-07  |            1

那么有什么不同呢?不能在子行上使用setSiteConfig,而是在siteConfig上调用addSelectors并传入要关联的选择器。请参阅下面的更新代码。

已将Promise变量更改为BPromise,因为节点现在有一个本机Promise模块,这将导致冲突。此外,我相信Sequelize内置了bluebird,所以你也可以只使用Sequelize.Promise

删除了spread调用中的嵌套promise,因为不需要它。

附带说明:Promise.all返回一个结果数组,所以我认为您不应该使用.spread()

var BPromise = require("bluebird");
var Sequelize = require("sequelize");
var sequelize = new Sequelize('test', 'root', 'password', {
  host: "localhost",
  dialect: "postgres",
  pool: {
    max: 5,
    min: 0,
    idle: 10000
  }
});
var Schedule = sequelize.define("Schedule", {
  website: {
    type: Sequelize.STRING
  }
});
var SiteConfig = sequelize.define("SiteConfig", {
  systemType: {
    type: Sequelize.STRING
  }
});
var Selector = sequelize.define("Selector", {
  type: {
    type: Sequelize.STRING
  },
  content: {
    type: Sequelize.STRING
  }
});
Selector.belongsTo(SiteConfig);
SiteConfig.hasMany(Selector);
var testSchedule = {
  website: "google.com"
};
var testSiteConfig = {
  systemType: "one"
};
var testSelectors = [
  {type: "foo", content: "foo"},
  {type: "foo", content: "bar"}
];
sequelize.sync({ force: true })
.then(function(result) {
  return BPromise.all([
    Schedule.create(testSchedule),
    SiteConfig.create(testSiteConfig),
    Selector.bulkCreate(testSelectors, { returning: true })
  ]);
})
.then(function(result) {
  var siteConfig = result[1];
  var selectors = result[2];
return siteConfig.addSelectors(selectors);
})
.then(function (result) {
  return this.siteConfig.getSelectors();
})
.each(function(result) {
  console.log('boomshakalaka:', result.get());
})
.catch(function(error) {
  console.log(error);
});