如何只在一个客户端上打开一个集合项?

时间:2015-01-13 14:05:07

标签: meteor

我有一个像这样的流星集合:

Cases = new Meteor.Collection('cases');

我也有注册用户(最多10个)。我现在希望能够向注册用户“提供”单个案例并确保没有其他用户获得该特定案例。

用户正在处理案例(更新字段,删除字段),然后在提交后将其发送到某种存档中,用户应该获得集合中的新案例。

我的想法是将字段称为“已锁定”,该字段最初设置为false,并且在用户“锁定”时显示的字段变为true并且不再返回:

return Cases.find({locked: false, done: false}, {limit: 1});

如何在流星中做到这一点?

由于

2 个答案:

答案 0 :(得分:0)

您只需要在案例中添加owner字段(或类似字段)即可。这将允许你做以下事情:

  • 只有publish案例的用户也是使用类似以下内容的用户:

Meteor.publish('cases/unassigned', function() {
    return Cases.find({owner: {$exists: false}});
});
Meteor.publish('cases/mine', function() {
    return Cases.find({owner: this.userId});
});
  • 如果用户未分配给用户,则allow用户无法更新或删除案例:

Cases.allow({
    update: function(userId, fieldNames, doc, modifier) {
        return userId === doc.owner;
    },
    delete: function(userId, doc) {
        return userId === doc.owner;
    }
});

显然,这些需要修改超级用户之类的东西,你可能需要定义一些methods来允许用户处理案例,但这是一般的想法。

答案 1 :(得分:0)

需要处理并发问题,才能将案例可靠地分配给一个人。

我们需要解决两件事: 1.可靠地将案例分配给用户 2.获取分配给用户的案例

2号很容易,但取决于1。

要解决1.,这应该有效:

var updated = Cases.update(
    {_id: <case-to-assign>, version: "ab92c91"},
    {assignedTo: Meteor.userId(), version: Meteor.Collection.ObjectID()._str});
if (updated) {
    // Successfully assigned
} else {
    // Failed to assign, probably because the record was changed first
}

使用此功能,您可以查询所有用户案例:

var cases = Cases.find({assignedTo: Meteor.userId()});

如果10个人同时尝试获取案例,则应该有一个预先设置的version字段,而MongoDB只会让.update工作一次。只要version字段发生更改(由于.update成功),剩余的更新就会失败,因为version字段无法再匹配。

既然分配已经可靠,那么抓取非常简单。

正如@Kyll所建议的那样,案例的过滤应该在Meteor出版物中完成。

在Meteor方法中执行大小写分配也是有意义的。

<强>更新

@ richsilv的解决方案比这个更简单,并且工作正常。

如果您需要立即知道谁赢了,而不向服务器发出进一步请求,此解决方案非常有用。