2015-04-02 72 views
3

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

我期望这个代码到SiteConfigId列添加到我的Selectors让我siteConfig.getSelectors()会回到我的testSelectors。我怎样才能做到这一点?

回答

2

[UPDATE]

事实证明我以前有过错。方法setSiteConfig()不是您想要使用的。我检查了数据库,它看起来像Sequelize创造了两个新的记录,而不是现有的富/酒吧选择关联:

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调用中的嵌套承诺,因为不需要它。我想你应该使用.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); 
}); 
+0

我还应该补充说我使用sequelize.sync()而不是同步每个单独的模型。 – 2015-04-03 17:24:53

+0

谢谢,您的代码正常工作!然而,我意识到,我的代码的主要问题是,我正在使用'bulkCreate'作为testSelectors而不是'create',它返回没有ID的插入行。从文档:http://docs.sequelizejs.com/en/latest/docs/instances/#working-in-bulk-creating-updating-and-destroying-multiple-rows-at-once 看来你的代码可以有相同的问题(虽然它不实际),你能帮我说明它为什么工作或编辑你的答案迭代testSelectors(而不是bulkCreate),我会很高兴地将它标记为接受:) – fredrikekelund 2015-04-04 10:48:36