[英]How should I keep my publication reactive?
I am migrating from a custom user rights management system to Alanning:roles v2.0 . 我正在从自定义用户权限管理系统迁移到Alanning:roles v2.0 。 I have a very basic structure: 我有一个非常基本的结构:
I was previously storing the group members and admins mongo _id
in the "group" document. 我之前在“组”文档中存储了组成员和管理员mongo _id
。 This way, I could publish the groups reactively : I just had to check if the userId
was in the group document, in the "members" or "admins" fields. 这样,我可以反应性地发布组:我只需要检查userId
是否在组成员文档中,在“成员”或“管理员”字段中。
Now that I switched to a right management enforced by Alanning:roles, I do something like this in my publication : 现在我切换到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
Note that Roles.getPartitionsForUser ()
is just the new function name for Roles.getGroupsForUser ()
. 需要注意的是Roles.getPartitionsForUser ()
仅仅是新的函数名称Roles.getGroupsForUser ()
The problem here is that the publication don't watch for changes in the role
collection, so when a user becomes member, the publication isn't updated. 这里的问题是发布不会监视role
集合中的更改,因此当用户成为成员时,不会更新发布。 I know this is a common issue and I know 3 ways to fix this, but none of them feels satisfying: 我知道这是一个常见的问题 ,我知道有3种方法可以解决这个问题,但是没有一种方法令人满意:
The best candidate: denormalize and duplicate. 最佳候选人:非规范化和重复。 I keep my members
and admins
fields in the group document. 我将我的members
和admins
字段保存在组文档中。 What bugs me is that I will keep 2 versions of the same thing and create a possibility for inconsistencies to appear. 让我感到困惑的是,我会保留同一件事的2个版本,并且可能会出现不一致的情况。
Add an argument to the publication and rerun it using this argument (eg userGroupsAsMember
) but it relies on client and makes it send unnecessary info. 向发布添加一个参数并使用此参数重新运行它(例如userGroupsAsMember
),但它依赖于客户端并使其发送不必要的信息。
Use low level publication api, either directly or using a package . 直接使用低级别的发布api或使用包 。 I already did this directly in the past but I don't want to rely on Cursor.observe()
anymore because it doesn't scale efficiently and create an unnecessary server load. 我已经在过去直接执行了此操作,但我不想再依赖Cursor.observe()
了,因为它无法有效扩展并创建不必要的服务器负载。
Am I missing an option? 我错过了一个选项吗? If not, what would be the best way to keep my publication reactive? 如果没有,那么保持我的出版物被动反应的最佳方式是什么?
Use reywood:publish-composite
to create a reactive join. 使用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
doesn't return a cursor, therefore it can't be reactive. Roles.getPartitionsForUser
不返回游标,因此它不能被动。 That's why you'll need to publish a Meteor.users.find
call, too. 这就是为什么你也需要发布一个Meteor.users.find
调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.