2015-04-02 79 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