当不存在水线关联时,Sails 服务 returns MongoDb 结果,但当它们存在时失败

Sails service returns MongoDb results when no Waterline associations exist but then fails when they DO exist

我正在构建一个 sails.js api 并将 MongoDb 作为我的数据库。

这些是我的模型(为了这个问题而简化):

models/Passport.js简化:

identifier: {
      type: 'string'
 },

owner: {
      model: 'User',
      required: true
 },

models/User.js简化:

username: {
        type: 'string',
        unique: true
 },
passports: {
        collection: 'Passport',
        via: 'owner'
}

问题

在 sails.js 服务 login 函数中,我首先尝试通过 User 集合中的用户名获取用户。

sails.models.user.findOne({username: 'demo'}).exec(function onExec(error, user)      {
    user; //contains user info
}

到目前为止一切顺利。

然后当获取用户(成功)时,我获取他的 user.id 并尝试从护照集合中获取他的护照。

sails.models.passport.findOne({owner:user.id}).exec(function onExec(error, passp) {
    if(passp==undefined)    //puppies dying in this line!!!!
        throw new Error('Can't find this passport');
    }
}

returned passp 对象未定义。 什么...为什么?

附加信息:

运行 > db.passport.find({owner:"theCorrectUserId"}) 在我的 mongo shell 中 return 是正确的护照,因此这不是身份证不正确的问题,而且,运行 :

sails.models.passport.find().exec(function onExec(error, passports) {
    passports; //does contain all my passports
}

包含我所有的护照。因此它也不是编程错误!

顿悟瞬间:

我用头撞墙几个小时后发现,删除关联,从而使我的模型像所以:

models/Passport.js简化:

identifier: {
      type: 'string'
 },

owner: {
      type: 'string'
      required: true
 }

models/User.js简化:

username: {
        type: 'string',
        unique: true
 }

确实解决了问题,并使我的 passp 对象获取正确的数据..

我使用水线协会错了吗?但是,为什么它在 mongo shell 关联存在时起作用?

我什至需要关联,因为我在我的服务中使用了 2 个不同的查询?性能怎么样?

让我们使用第一个模型架构。

这就是你应该如何使用 Waterline:

sails.models.user
    .findOne({ username: username })
    // The populate method allows you to get associated data
    .populate('passports') 
    .exec(function (err, user) {
        // Handle errors
        if(err) return next('An unknown error has occured');
        if(!user) return next('Can\'t find this user');

        if(!user.passports || !user.passports.length)
            return next('This user has no passports');

        // The User has at least one passport
        ...

        return next(null, user);
}

next 方法将您带回您的控制器。以下是您应该如何使用您的服务:

sails.services.myService
    .login(username, password, function (err, user) {
         ...
});

如您所见,只剩下一个查询:-)。

这是关于 associations with the Sails ORM 的文档。

而不是做:

sails.models.passport.findOne({owner:user.id})

尝试:

sails.models.passport.findOne({owner:user})