userId神奇地进入文档

时间:2016-04-01 05:31:34

标签: meteor

这个Meteor代码工作正常,但我想问一下,这是Meteor做事的方式,还是一种不可预测的副作用,可能会在以后某种情况下发生变化。
事情是,当我这样做  DisplayCol.insert({action: 'task1', element: 'p', value: value_variable});
Meteor还插入了正确的userId(使用2个不同的浏览器作为2个不同的用户登录),我没有明确包含在文档中。

上面的代码行位于从Meteor方法调用的服务器端函数内。

这是相关信息;

// LIB / collection.js
DisplayCol = new Mongo.Collection('displayCol');

// server.js

Meteor.publish('displayCol', function () {
  return DisplayCol.find({userId: this.userId});
});
DisplayCol.before.insert(function (userId, doc) {
  doc.userId = userId;
});

docs 的Collection hooks>中附加说明>第二个项目符号段落说:

  

userId可用于查找和查找在发布函数中调用的一个查询。

但这是一个collection.insert。那么我应该在文档中明确地包含userId还是让集合钩子做它隐藏的魔术?感谢

1 个答案:

答案 0 :(得分:2)

不,该代码中没有隐藏的魔法,您的before挂钩正在文档中插入userId字段。

当您执行此类insert时,

DisplayCol.insert({action: 'task1', element: 'p', value: value_variable});

您要插入的doc{ action: 'task1', element: 'p', value: value_variable }

因为,你有这个钩子,

DisplayCol.before.insert(function (userId, doc) {
    doc.userId = userId;
});

在插入集合之前更改doc。因此,上述摘要会将您的doc更改为{action: 'task1', element: 'p', value: value_variable, userId: 'actual-user-id' }

预期的行为。

关于你在问题中的另一点,

  

userId可用于查找和查找已调用的查询   在发布功能中。

userIdfind之前的findOne参数返回null,因此用户需要将userId作为参数传递{{3} }}。附加说明提到不再需要黑客攻击。它与将userId字段插入集合文档无关。

要进行快速测试,请移除上方的DisplayCol.before.insert挂钩,您不会在新插入的文档中看到userId字段。

<强>更新

从您提供的文档中的第4点开始,进一步澄清您的疑问

  

userId有时无法挂钩是很正常的   在某些情况下回调。例如,如果触发更新   从服务器没有用户上下文,服务器肯定不会   能够提供任何特定的userId。

这意味着如果在服务器上插入或更新文档,则不会有与服务器关联的用户,在这种情况下,userId将返回null。

您也可以自己查看源代码comment。检查CollectionHooks.getUserId方法,它使用Meteor.userId()获取userId

CollectionHooks.getUserId = function getUserId() {
  var userId;

  if (Meteor.isClient) {
    Tracker.nonreactive(function () {
      userId = Meteor.userId && Meteor.userId(); // <------- It uses Meteor.userId() to get the current user's id
    });
  }

  if (Meteor.isServer) {
    try {
      // Will throw an error unless within method call.
      // Attempt to recover gracefully by catching:
      userId = Meteor.userId && Meteor.userId(); // <------- It uses Meteor.userId() to get the current user's id 
    } catch (e) {}

    if (!userId) {
      // Get the userId if we are in a publish function.
      userId = publishUserId.get();
    }
  }

  return userId;
};