Sails.js/Waterline填充深度嵌套关联

Sails.js/Waterline populate deep nested association

本文关键字:深度 嵌套 关联 填充 Waterline js Sails      更新时间:2023-09-26

我知道Sails.js/Waterline中还没有内置的方法来填充深度嵌套关联,所以我试图使用bluebird promise来实现这一点,但我遇到了一个问题。

我成功地检索了该用户以及与之相关的所有帖子(用图像集合填充)(console.log向我显示所有内容都已正确填充)。然而,当我覆盖用户的属性"post"并尝试分配之前检索到的完全填充的posts时,它没有正确填充post.js的images属性。这就像ORM阻止手动分配post.js中的图像集合一样。

我做错了什么?填充深度嵌套的一对多关联的最佳方式是什么?

贝娄我已经粘贴了我正在执行的所有代码。。。。

// Populate nested association
nested: function (req, res, next){
var username = req.param("id");
User
.findOneByUsername(username)
.populateAll()      
.then(function (user){
    var posts = Post.find({
        "user": user.id
    })
    .populate('images')
    .populate('category')
    .then(function (posts){
        return posts;
    });
    return [user, posts];
})
.spread(function (user, posts){
    user.posts = posts; // This won't work.... It assigns all the fields properly but the images collection attribute
    res.json(user);
}).catch(function (err){
    if (err) return res.serverError(err);
});
}
// --- User.js Model --- //
module.exports = {
   attributes: {
    .....,
    posts: {
        collection: "post",
        via: "user"
    },
    .....
   }
 }
// --- Post.js Model --- //
module.exports = {
    attributes: {
       ....,
       user: {
         model: "user"
       },
       images: {
         collection: "postImage",
         via: "post"
       },
       ....
    }
}
// --- PostImage.js Model --- //
module.exports = {
   attributes: {
     ....,
     post: {
       model: "post"
     }
   },
}

问候,

Sávio Lucena

这可能是一个老问题,但最好有一个答案,所以sails.js用户可以从中受益。

这里的问题是,当sails返回一个记录(在数组中)时,该记录中对应于关联的键实际上是getters/ssetters,并且setter似乎不允许您想要的内容。您可以使用Object.getOwnPropertyDescriptor(user, 'posts')进行确认。因此,为了能够根据需要覆盖该属性,您需要做的是对其调用.toObject,(或通过_.clone或手动循环克隆其属性,但会收到很多垃圾,所以请坚持使用.toObject),在任何情况下,您都会得到一个具有所需属性的新对象,并且现在修改它的方式没有限制。

所以你的代码看起来是这样的:

User
.findOneByUsername(username)
.populateAll()      
.then(function (user){
    var posts = Post.find({
        "user": user.id
    })
    .populate('images')
    .populate('category')
    .then(function (posts){
        return posts;
    });
    return [user, posts];
})
.spread(function (user, posts){
    user = user.toObject() // <- HERE IS THE CHANGE!
    user.posts = posts; // It will work now
    res.json(user);
}).catch(function (err){
    if (err) return res.serverError(err);
});
}

您必须覆盖user.posts数组中的每个post-id对象。有关更多信息,请查看此答案https://stackoverflow.com/a/26452990/4261327.