简体   繁体   English

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

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

I'm using Sequelize and I'm trying to create associations between two different tables, where x.belongsTo(y) and y.hasMany(x) . 我正在使用Sequelize,我正在尝试在两个不同的表之间创建关联,其中x.belongsTo(y)y.hasMany(x) After having done x.setY(yInstance) and y.getXs() it seems only new rows have been added to x and no associations to my already created instances have been created. 在完成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"));
    });
});

I'd expect this code to add a SiteConfigId column to my Selectors so that my siteConfig.getSelectors() would return my testSelectors. 我希望这段代码将一个SiteConfigId列添加到我的Selectors以便我的siteConfig.getSelectors()返回我的testSelectors。 How can I achieve this? 我怎样才能做到这一点?

[UPDATE] [UPDATE]

It turns out what I had earlier was wrong. 事实证明我之前的错误。 The method setSiteConfig() is not what you want to use. setSiteConfig()方法不是您想要使用的方法。 I checked the db and it looks like Sequelize created two new records instead of associating the existing foo/bar selectors: 我检查了数据库,看起来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

So what is different? 那有什么不同呢? You can't use setSiteConfig on the child rows, instead you call addSelectors on siteConfig and pass in the selectors you want to associate. 您不能在子行上使用setSiteConfig ,而是在siteConfig上调用addSelectors并传入要关联的选择器。 See updated code below. 请参阅下面的更新代码

Changed Promise variable to BPromise because node has a native Promise module now which would cause a conflict. Promise变量更改为BPromise因为节点现在具有本机Promise模块,这会导致冲突。 Also I believe Sequelize has bluebird built-in so you can also just use Sequelize.Promise . 另外我相信Sequelize内置蓝鸟,所以你也可以使用Sequelize.Promise

Removed the nested promise in your spread call because there is no need for it. 在您的spread通话中删除了嵌套的承诺,因为不需要它。

Side note: Promise.all returns a single result array so I don't think you should be using .spread() . 旁注: 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);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM