集合拒绝规则属性未定义

时间:2017-05-10 09:52:23

标签: meteor

在浏览器控制台中调用时:
Meteor.users.update({_id:'2MA7iPq7bNtfxGm6r'},{$unset:{'profile.taskInProgress':''}})

此Meteor服务器代码提供此错误

  

TypeError:无法读取未定义

的属性'profile.taskInProgress'
Meteor.users.deny({
  update: function (userId, doc, fields, modifier) {
    const tasks = ['search', 'aSearch'];
    return (!(
      userId &&
      userId == Meteor.userId() &&
      (tasks.indexOf(modifier.$set['profile.taskInProgress']) >= 0) || //<--comment for next line to work
      (modifier.$unset['profile.taskInProgress'] == '') // <-- or comment for the above line to work
    ));
  }
});

如果我注释掉“错误行”,它会起作用,但如果我这样做,那么我将失去对$设置它的权限。所以现在看起来我可以拥有一个或另一个但不是两个权限。我的代码一定是个问题。

如何让客户端取消设置'profile.taskInProgress'属性?

1 个答案:

答案 0 :(得分:0)

我认为你有一个逻辑问题。

你的表达基本上是这样的:

!(a && b && c || d)

c仅在您执行$ set时有效,且d仅在您执行$ unset时有效。

如果你的表达是这样的(没有前缀爆炸):

(a && b && c || d)

...然后,对于$ set,评估将是:a,b,c。如果这些都是真的,那么条件就满足了。它不需要继续评估d。这很好,因为我认为由于缺乏空检而失败。

但是如果使用$ unset,那么我相信c会失败,因为缺少空检查。 (我在这里不是正面的,但我认为这是“正在发生的事情”。

但是,你有完整的表达&#34;注意到&#34;。无论是否使用$ set或$ unset,它都会强制评估a,b,c和d中的每一个。由于缺乏空检查,这总是会失败。

我认为你真正的意思是:

!(a && b && (c || d))

如上所述,你可以拥有userId,只要d为真(并且进行了空检查),你就可以进行操作。

要解决它,我会打破整体逻辑的评价。 e.g。

let userIdExists = !!userId;
let requesterIsLoggedInUser = (userId === Meteor.userId());
let progressSet = (modifier.$set && (tasks.indexOf(modifier.$set['profile.taskInProgress']) >= 0));
let progressUnset = (modifier.$unset && (modifier.$unset['profile.taskInProgress'] == ''));

let allowed = userIdExists && requesterIsLoggedInUser && (progressSet || progressUnset);

let denied = !allowed;

return denied;

我倾向于在这样的逻辑情境中冗长,以确保每个条件都易于理解。

顺便问一下,为什么这不作为允许规则表示?返回&#34;允许&#34;而不是&#34;!允许&#34;在一个否定似乎更容易阅读,imho。

编辑:允许版本只执行&#34;允许返回;&#34;最后,而不是打扰被拒绝的变量。

如果您正在尝试调试,则调试所有变量的console.log()以查看它们是否符合您的预期。如果你愿意,可以用修改器的那些结果和控制台日志更新你的问题,这样就可以更容易地确认progressSet和progressUnset的逻辑。