Sequelize 关联:set[Models] 添加新模型而不是关联现有模型
Sequelize associations: set[Models] adds new models instead of associating existing ones
我正在使用 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()
将 return 我的 testSelectors。我怎样才能做到这一点?
[更新]
原来我之前的想法是错误的。 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 内置了蓝鸟,所以你也可以只使用 Sequelize.Promise
.
删除了您的 spread
调用中的嵌套承诺,因为不需要它。
旁注:Promise.all
returns 单个结果数组,所以我认为您不应该使用 .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);
});
我正在使用 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()
将 return 我的 testSelectors。我怎样才能做到这一点?
[更新]
原来我之前的想法是错误的。 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 内置了蓝鸟,所以你也可以只使用 Sequelize.Promise
.
删除了您的 spread
调用中的嵌套承诺,因为不需要它。
旁注:Promise.all
returns 单个结果数组,所以我认为您不应该使用 .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);
});