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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26535727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 06:06:24  来源:igfitidea点击:

Sails.js/Waterline populate deep nested association

javascriptsails.jswaterline

提问by Sávio Lucena

I understand that there is no built-in way in Sails.js/Waterline of populating deep nested associations yet, so I am trying to use bluebird promises to accomplish that but I'm running into a problem.

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

I'm successfully retrieving the user, and all the posts (populated with the images collection) associated with it (console.log shows me that everything is filled properly). However, when I override the property "post" of the user and try to assign the fully populated posts retrieved before, it does not fill properly the images property of Post.js. It is like the ORM is preventing the image collection of Post.js to be manually assigned.

我成功地检索了用户以及与其关联的所有帖子(填充了图像集合)(console.log 显示所有内容都已正确填写)。但是,当我覆盖用户的“post”属性并尝试分配之前检索到的完全填充的帖子时,它没有正确填充 Post.js 的图像属性。这就像 ORM 阻止手动分配 Post.js 的图像集合。

What am I doing wrong? What is the best way of populating deep nested one-to-many associations?

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

Bellow I've pasted all the code that I'm executing....

波纹管我已经粘贴了我正在执行的所有代码......

// 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"
     }
   },
}

Regards,

问候,

Sávio Lucena

萨维奥卢塞纳

回答by Lu Roman

This might be an old question, but its better to have an answer, so sails.js users can benefit of it.

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

Your issue here is that when sails returns a record (Inside an array), the keys of that record that correspond to associations, are in fact getters/setters, and it seems that the setter does not allows what you want. You can use Object.getOwnPropertyDescriptor(user, 'posts')to confirm. So what you need to do in order to be able to override that property as you want, is to call .toObjecton it, (or clone its properties via _.cloneor manually looping but you'll get a lot of junk with it, so stick to the .toObject), in any case you get a new object with the properties you need, and there is no restriction in how you modify it now.

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

So your code will look like this:

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

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);
});
}

回答by Jani

You have to overwrite each post id object in user.posts array. For more info check this answer https://stackoverflow.com/a/26452990/4261327.

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