例如,当您的权限是基于组的,并且您的用户文档包含用户所属的组列表时。我在Items集合中发布文档,您应该只能查看groupOwner
字段与您所属的组匹配的项目。
如果您可以在发布内部自动运行会很好,但我怀疑您可以:
Meteor.publish 'screened-items', ->
Deps.autorun ->
user = Users.findOne @userId
return Items.find {groupOwner: {$in: user.groups}}
如果你不能,这是我能想到的最好的,但它会变得缓慢且占用大量内存。这是唯一的方法吗?
Meteor.publish 'screened-items', ->
user = Users.findOne @userId
# (hope that the db doesn't change between this line and the observeChanges)
saved_items = Items.find({groupOwner: {$in: user.groups}}).fetch()
# call @added on each item
handle = Users.findOne(@userId).observeChanges {
changed: (_, fields) =>
if fields.groups
new_items = Items.find({groupOwner: {$in: fields.groups}}).fetch()
# compare new_items to saved_items, and call @added() or @removed() for each difference
}
@ready()
@.onStop ->
handle.stop()
答案 0 :(得分:1)
您可以通过以下两种方式实现:
使用publish-with-relations
包,例如:
Meteor.publish 'screend-items', ->
# select the current user
Meteor.publishWithRelations
handle: this
collection: Meteor.users
filter:
_id: @userId
options:
fields:
groups: 1
mappings: [
key: 'groupOwner' # and map to the `groupOwner` field on Items
collection: Items
]
对关系进行非规范化,提供用于发布的简洁用户列表
Items._ensureIndex(userIds: 1) # best to index this field
# basic publications
Meteor.publish 'screend-items', ->
# don't expose `userIds` to the client
return Items.find({userIds: @userId}, {fields: userIds: false})
答案 1 :(得分:1)
如果您希望在userId更改时更改已发布的文档,则这是默认行为。
但是,如果登录用户更改,则会使用新值重新运行发布功能。 - 来自docs.meteor.com。
Deps.autorun()仅适用于客户端,而Meteor.publish()仅适用于服务器。所以你不能在发布内部自动运行。
如果您可以让客户端看到他们所在的“群组”,则代码会更简单,因为您可以在群组更改时启动和停止订阅。像这样:
//on client
Deps.autorun( function() {
Meteor.subscribe( 'items', Meteor.user().groups );
});
//on server
Meteor.publish( 'items', function( groups ){
var self = this;
var user = Meteor.users.findOne( {_id: self.userId});
if ( ! (user && user.groups === groups) )
return;
return Items.find({groupOwner: {$in: groups}});
});
否则,您需要在发布功能中使用两个观察者 - 一个用于监视用户对组的更改,另一个用于管理组中的发布项目。请参阅this example以这种方式加入集合。