风帆模型查询
Sails model query
我有 3 个模型(房间、模块和设备):
房间:
/**
* Room.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/
module.exports = {
attributes : {
name : {
type : 'string',
required : true
},
image : {
type : 'binary'
},
modules : {
collection : 'Module',
via : 'inRoom'
},
toJSON : function ()
{
var obj = this.toObject();
if (obj.image)
{
var base64data = new Buffer(obj.image.toString(), 'binary').toString();
obj.image = base64data;
}
return obj;
}
},
beforeCreate : function (attrs, next)
{
next();
}
,
beforeUpdate : function (attrs, next)
{
next();
}
}
;
模块:
/**
* Module.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/
module.exports = {
attributes : {
name : {
type : 'string',
required : true
},
nbDevices : {
type : 'integer',
defaultsTo : 1
},
image : {
type : 'binary'
},
inRoom : {
model : 'Room'
},
devices : {
collection : 'Device',
via : 'module'
}
}
};
设备:
/**
* Device.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/
module.exports = {
attributes : {
name : {
type : 'string',
required : true
},
index : {
type : 'integer',
defaultsTo : 0
},
value : {
type : 'integer',
defaultsTo : 0
},
image : {
type : 'binary'
},
module : {
model : 'Module'
}
}
};
我想取回我所有的房间,里面有所有的设备。现在我喜欢这样:
Room.find().populate('modules')
.exec(function (err, rooms)
{
var index = 0;
var total = rooms.length-1;
_(rooms).forEach(function (room)
{
Device.find({module : _.pluck(room.modules, 'id')}).populate("module").exec(function (err, data)
{
room.devices = data;
console.log(room);
if(total == index)
{
return res.json(rooms);
}
index++;
});
}).value();
});
但它看起来不像 clean/safe 方法。还有另一种方法可以实现这一目标吗?
我看到这个 post Sails.js populate nested associations 但无法使用 find 而不是 findOne。
您可以使用您在回答中提到的 async or some other library for control flow to add to the example 来执行以下操作:
var async = require('async');
Room.find()
.populate('modules')
.exec(function (err, rooms) {
// if(err) ...
async.forEach(room,
// apply on each room
function(room, cb){
if(err || !room) return cb(err);
Device.find({module : _.pluck(room.modules, 'id')})
.populate("module")
.exec(function(err, devices){
room.devices = devices;
cb();
});
},
// when all rooms are done
function(err){
// if(err) ...
res.json(rooms);
}
);
});
我有 3 个模型(房间、模块和设备): 房间:
/**
* Room.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/
module.exports = {
attributes : {
name : {
type : 'string',
required : true
},
image : {
type : 'binary'
},
modules : {
collection : 'Module',
via : 'inRoom'
},
toJSON : function ()
{
var obj = this.toObject();
if (obj.image)
{
var base64data = new Buffer(obj.image.toString(), 'binary').toString();
obj.image = base64data;
}
return obj;
}
},
beforeCreate : function (attrs, next)
{
next();
}
,
beforeUpdate : function (attrs, next)
{
next();
}
}
;
模块:
/**
* Module.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/
module.exports = {
attributes : {
name : {
type : 'string',
required : true
},
nbDevices : {
type : 'integer',
defaultsTo : 1
},
image : {
type : 'binary'
},
inRoom : {
model : 'Room'
},
devices : {
collection : 'Device',
via : 'module'
}
}
};
设备:
/**
* Device.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/
module.exports = {
attributes : {
name : {
type : 'string',
required : true
},
index : {
type : 'integer',
defaultsTo : 0
},
value : {
type : 'integer',
defaultsTo : 0
},
image : {
type : 'binary'
},
module : {
model : 'Module'
}
}
};
我想取回我所有的房间,里面有所有的设备。现在我喜欢这样:
Room.find().populate('modules')
.exec(function (err, rooms)
{
var index = 0;
var total = rooms.length-1;
_(rooms).forEach(function (room)
{
Device.find({module : _.pluck(room.modules, 'id')}).populate("module").exec(function (err, data)
{
room.devices = data;
console.log(room);
if(total == index)
{
return res.json(rooms);
}
index++;
});
}).value();
});
但它看起来不像 clean/safe 方法。还有另一种方法可以实现这一目标吗? 我看到这个 post Sails.js populate nested associations 但无法使用 find 而不是 findOne。
您可以使用您在回答中提到的 async or some other library for control flow to add to the example 来执行以下操作:
var async = require('async');
Room.find()
.populate('modules')
.exec(function (err, rooms) {
// if(err) ...
async.forEach(room,
// apply on each room
function(room, cb){
if(err || !room) return cb(err);
Device.find({module : _.pluck(room.modules, 'id')})
.populate("module")
.exec(function(err, devices){
room.devices = devices;
cb();
});
},
// when all rooms are done
function(err){
// if(err) ...
res.json(rooms);
}
);
});