What I would like to accomplish is: get all users with the role of 'admin', is there an easier way to do this in loopback?
app.models.role.findOne({where: {name: 'admin'}, function(err, adminRole) {
adminRole.users(function(err, users) {
...
});
});
Well, the following code doesn't work
adminRole.users(function(err, users) {
...
});
I changed the code to the following and then get it working correctly.
User.getAdminUsers = function(callback) {
Role.findOne({where: {name: 'admin'}}, function(err, adminRole) {
if(adminRole) {
console.log(adminRole);
RoleMapping.find({where: {roleId: this.id,
principalType: RoleMapping.USER}}, function (err, mappings) {
if (err) {
callback && callback(err);
//return;
}
var users = mappings.map(function (m) {
return m.principalId;
});
console.log(users);
callback(null, users);
});
/*adminRole.users(function(err, users) {
if(users) {
console.log(users);
callback(null, users);
} else {
console.log(err);
callback(err);
}
});*/
} else {
console.log(err);
callback(err);
}
});
Actually I am working on a project created via slc lb project myapp, so there is a new roleMapping in the models.json file which extends the RoleMapping model.
Still for your own code I cannot get anything back for the users. and here is the code I tracked down in the node-inspector
// Set up the connection to users/applications/roles once the model
Role.once('dataSourceAttached', function () {
var roleMappingModel = this.RoleMapping || loopback.getModelByType(RoleMapping);
Role.prototype.users = function (callback) {
roleMappingModel.find({where: {roleId: this.id,
principalType: RoleMapping.USER}}, function (err, mappings) {
if (err) {
callback && callback(err);
return;
}
return mappings.map(function (m) {
return m.principalId;
});
});
};
I guess this issue (#274) might be able to answer why your code doesn't work for me, by the way, I am also using MongoDB as my data source.
Any update on this issue?
Seems there are several open issues with roles not correctly being included with users. The way I ended up making this work was:
server/boot/role-mapping.js
module.exports = function(app) {
var RoleMapping = app.models.RoleMapping;
/**
* Get user ID's by role name
* @param role
* @param callback
*/
RoleMapping.usersIDByRole = function(role, callback){
RoleMapping.app.models.Role.byName(role, function(err, role){
if( err || !role ) return callback(err);
RoleMapping.find({
where: {
roleId: role.id,
principalType: RoleMapping.USER
}
}, function(err, mappings){
if( err ) return callback(err);
var users = mappings.map(function (m) {
return m.principalId;
});
callback(null, users);
});
});
}
};
Then in my users model common/models/user.js
/**
* Return users by role
* @param role
* @param callback
*/
User.getUsersByRole = function(role, callback) {
User.app.models.RoleMapping.usersIDByRole(role, function(err, users) {
if( err || !users ) return callback(err);
User.find({
where : {
_id : {inq : users}
}
}, callback);
});
};
@mneil Thanks, your solution is working fine. However in RoleMapping.app.models.Role.byName, the function byName is saying undefined. Hence, I have modified the above portion as follows
RoleMapping.app.models.Role.findOne({where: {name:role}}, function(err, role){
// ...
});
Ah yes, sorry @hilarudeensa I didn't define that function in my example.
In ./server/boot/role.js
module.exports = function(app) {
var Role = app.models.Role;
/**
* Get a role by name
* @param name
*/
Role.byName = function(name, callback){
Role.findOne({where: {name: name}}, callback);
}
}
I also added slightly better error checking to the above examples as I found that it was throwing an exception if I searched for a role that didn't exist. In my case the role should always exist but I have tests for if it doesn't and they were failing without better error checking.
Are you guys still running into issues? Can I close this?
I think you should close this issue. It's related to https://github.com/strongloop/loopback/issues/1441. I was just suggesting a workaround that I used. A couple of the suggestions about coercing the id to a mongo ObjectId in the issue I just linked to really is a better solution though.
@mneil Thanks for the response. Closing.
Please open a new issue if you guys are still running into problems.
Please note that the adminRole.users method used in @raymondfeng's solution is currently broken. I've submitted a simple fix in PR #2742.