如何使用Sails 0.10.x在一对多关系中引用关联模型

How to reference associated models in a one-to-many relationship with Sails 0.10.x

本文关键字:关系 引用 关联 模型 一对多 Sails 何使用      更新时间:2023-09-26

我使用的是Sails.js 0.10版本。x,我刚刚开始尝试associactions的东西。

在我的场景中,我有一个用户,他有许多文档。

所以在/api/models/User.js中我有:

module.exports = {
  // snipped out bcrypt stuff etc
  attributes: {
     email: {
      type: 'string',
      unique: true,
      index: true,
      required: true
    },
    documents: {
      collection: 'document',
      via: 'owner'
    },
  }
};

和在/api/models/Document.js我有:

module.exports = {
  attributes: {
    name:      'string',
    owner: {
      model: 'user'
    }
  }
};

在我的DocumentController中我有以下内容:

fileData = {
  name: file.name,
  owner: req.user
}
Document.create(fileData).exec(function(err, savedFile){
  if (err) {
    next(err);
  } else {
    results.push({
      id: savedFile.id,
      url: '/files/' + savedFile.name,
      document: savedFile
    });
    next();
  }
});

通过命令行查看我的本地mongo数据库,我可以看到文档的所有者字段设置如下"owner" : ObjectId("xxxxxxxxxxxxxxxxxxxxxxxx"),这是预期的。

然而,当我稍后在DocumentController中通过sails.log.debug("user has documemts", req.user.documents);检查req.user对象时,我看到

debug: user has documents [ add: [Function: add], remove: [Function: remove] ]

而不是Document对象的数组

在我的slim模板

if req.user.documents.length > 0
  ul
    for doc in req.user.documents
      li= doc.toString()
else
  p No Documents!

我总是收到"No Documents!"

我似乎错过了一些明显的东西,但我不确定那是什么

我通过仔细阅读Waterline源代码得出了这个问题。

首先,正如我所希望的那样,关联的双方都受到Document实例创建的影响,我只需要重新加载我的用户。

在控制器中,这就像User.findOne(req.user.id).populateAll().exec(...)

一样简单

我还修改了我的passport服务助手如下

function findById(id, fn) {
  User.findOne(id).populateAll().exec(function (err, user) {
    if (err) return fn(null, null);
    return fn(null, user);
  });
}
function findByEmail(email, fn) {
  User.findOne({email: email}).populateAll().exec(function (err, user) {
    if (err) return fn(null, null);
    return fn(null, user);
  });
}

现在user和它的关联,每个请求都被正确加载。

我不得不挖掘源代码来找到populateAll()方法,因为它实际上没有记录在我能找到的任何地方。我也可以使用populate('documents')代替,但我即将向用户添加其他关联,因此需要populateAll()来加载所有相关的关联。

  • 水线associations docs
  • 水线/lib/waterline/query/deferred.js#populateAll