Sails.js/Waterline заполняют глубоко вложенную ассоциацию

Я понимаю, что в Sails.js/Waterline нет встроенного встраивания глубоких вложенных ассоциаций, поэтому я пытаюсь использовать bluebird promises, чтобы выполнить это, но у меня проблема.

Я успешно извлекаю пользователя и все связанные с ним записи (заполненные коллекцией изображений) (console.log показывает мне, что все заполнено правильно). Однако, когда я переопределяю свойство "пост" пользователя и пытаюсь назначить полностью заполненные сообщения, полученные ранее, он не правильно заполняет свойство изображений Post.js. Это похоже на то, что ORM препятствует назначению коллекции изображений Post.js вручную.

Что я делаю неправильно? Каков наилучший способ заполнения глубоко вложенных ассоциаций "один ко многим"?

Bellow Я вставил весь код, который я выполняю....

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

Привет,

Савио Лусена

Ответ 1

Это может быть старый вопрос, но лучше иметь ответ, поэтому пользователи sails.js могут извлечь из этого выгоду.

Ваша проблема заключается в том, что когда sails возвращает запись (внутри массива), ключи этой записи, соответствующие ассоциациям, на самом деле являются getters/seters, и кажется, что 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);
});
}

Ответ 2

Вы должны перезаписать каждый объект post id в массиве user.posts. Для получения дополнительной информации проверьте этот ответ fooobar.com/info/122348/....