我正在从自定义用户权限管理系统迁移到Alanning:roles v2.0。我有一个非常基本的结构:
我之前在“群组”文档中存储了群组成员和管理员mongo _id
。通过这种方式,我可以反复发布群组:我只需检查userId
是否在群组文档中,“成员”或“管理员”字段中。
现在我切换到Alanning强制执行的正确管理:角色,我在我的出版物中做了类似的事情:
const userGroupsAsAdmin = Roles.getPartitionsForUser (this.userId, ['group_admin'])
const userGroupsAsMember = Roles.getPartitionsForUser (this.userId, ['member'])
const selector = {$or:[{'_id':{$in: userGroupsAsMember}},{'_id':{$in: userGroupsAsAdmin}}]}
const options = {}
const response = Groups.find(selector, options)
return response
请注意,Roles.getPartitionsForUser ()
只是Roles.getGroupsForUser ()
的新功能名称。
此处的问题是发布不会监视role
集合中的更改,因此当用户成为成员时,不会更新发布。我知道this is a common issue并且我知道有3种方法可以解决这个问题,但是没有一种方法让我感到满意:
最佳候选人:反规范化和重复。我将members
和admins
字段保留在组文档中。让我感到困惑的是,我会保留同一件事的两个版本并产生出现不一致的可能性。
为发布添加一个参数并使用此参数重新运行它(例如userGroupsAsMember
),但它依赖于客户端并使其发送不必要的信息。
直接或使用package使用低级别发布API。我已经在过去直接这样做了,但我不想再依赖Cursor.observe()
了,因为它不能有效扩展并造成不必要的服务器负载。
我错过了一个选项吗?如果不是,那么保持我的出版物被动反应的最佳方式是什么?
答案 0 :(得分:2)
使用reywood:publish-composite
创建反应式连接。
Meteor.publishComposite("my-groups", {
find: function() {
// findOne won't work, it's not a cursor
return Meteor.users.find(
{_id: this.userId},
{fields: {roles: 1}}
);
},
children: [{
find: function(user) {
// getPartitionsForUser allows the first parameter to be the actual user object.
const userGroupsAsAdmin = Roles.getPartitionsForUser (user, ['group_admin']);
const userGroupsAsMember = Roles.getPartitionsForUser (user, ['member']);
const selector = {$or:[{'_id':{$in: userGroupsAsMember}},{'_id':{$in: userGroupsAsAdmin}}]};
const options = {};
const response = Groups.find(selector, options);
return response;
}
}]
});
Roles.getPartitionsForUser
不会返回光标,因此无法进行反应。这就是为什么您也需要发布Meteor.users.find
来电。