Reputation: 390
I'm trying to create a simple one-to-many assocation using sails 0.10.x with mongoDB. I have two models, Game and Map, which a game can have multiple maps associated to its account. Using populate I can correctly get all the maps associated to the game, but the inverse operation doesn't work. I cannot get the game data using populate from Map.
here are my models:
//Game.js
module.exports = {
attributes: {
name:{
type: 'string',
required: true
},
maps: {
collection: 'map',
via: 'game'
}
}
//Map.js
module.exports = {
attributes: {
name: {
type: 'string',
required: true
},
game:{
model: 'game'
}
}
//test data:
Game.create({
id: 200,
name: 'game1'});
Map.create({
id: 300,
name: 'map1',
game: 200
});
If I use
Game.find().populate("maps").exec(console.log);
it correclty returns the maps associated to the game:
{ maps:
[ { name: 'map1',
game: '200',
id: '300' } ],
name: 'game1'}
but the inverse command, trying to retrieve the game data from map, returns a undefined game property:
Map.find().populate("game").exec(console.log)
returns:
{ name: 'map1',
game: undefined,
id: '300' }
Even trying using a parameter in find(), I got the same result.
Double checked my code with the Sails and waterline documentation but could't figure out what I'm doing wrong.
Sails doc.: http://sailsjs.org/#/documentation/concepts/ORM/Associations/OnetoMany.html
Waterline doc.:https://github.com/balderdashy/waterline-docs/blob/master/associations.md
UPDATE
I figured out that, if I create the test data without forcing the IDs I want, it works perfectly:
Game.create({name: 'game1'}).exec(console.log);
Game.findOne({name: 'game1'}, function (err, game){
Map.create({
name: 'map1',
game: game.id
}).exec(console.log);
});
now I can get the owner data. Since it works when I use the mongoDB ids, I believe it is some issue related to the connector.
Map.find().populate("game").exec(console.log)
//returns (ommited the original IDs
[ { game:
{ name: 'game1', id: 'xxx100' },
name: 'map1',
id: 'xxx300' } ]
Thanks!
Upvotes: 4
Views: 947
Reputation: 390
I figured out that, if I create the test data without forcing the IDs I want, it works perfectly:
Game.create({name: 'game1'}).exec(console.log);
Game.findOne({name: 'game1'}, function (err, game){
Map.create({
name: 'map1',
game: game.id
}).exec(console.log);
});
now I can get the owner data.
Since it works when I use the mongoDB ids, I believe it is some issue related to the connector.
Map.find().populate("game").exec(console.log)
//returns (ommited the original IDs)
[ { game:
{ name: 'game1', id: 'xxx100' },
name: 'map1',
id: 'xxx300'
}
]
Upvotes: 0
Reputation: 24948
If you're using MongoDB and you don't want to use the default Mongo IDs, you need to configure your models accordingly. For example:
//Game.js
module.exports = {
// Don't use automatic primary key
autoPK: false,
attributes: {
// Create your own ID field manually
id: {
type: 'integer',
primaryKey: true
},
name:{
type: 'string',
required: true
},
maps: {
collection: 'map',
via: 'game'
}
}
}
This will allow associations and other operations to work correctly. Mind you, if you do this then you'll be responsible for guaranteeing unique integer IDs; MongoDB doesn't have an "autoincrement" property.
Upvotes: 1