Sails.js/Waterline populate deep nested association

被刻印的时光 ゝ 提交于 2019-12-30 17:22:28

问题


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.

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.

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


回答1:


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

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 .toObject on it, (or clone its properties via _.clone or 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.

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



回答2:


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



来源:https://stackoverflow.com/questions/26535727/sails-js-waterline-populate-deep-nested-association

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!