2014-10-23 12 views
10

Ich verstehe, dass es in Sails.js/Waterline keine eingebaute Weise gibt, tief verschachtelte Assoziationen noch zu bevölkern, also versuche ich, Bluebirdversprechungen zu benutzen, um das zu erreichen, aber ich bin in ein Problem geraten.Sails.js/Waterline bevölkern tiefe verschachtelte Assoziation

Ich bin erfolgreich Abrufen des Benutzers, und alle Beiträge (mit der Bildersammlung gefüllt) damit verbunden (console.log zeigt mir, dass alles richtig gefüllt ist). Wenn ich jedoch die Eigenschaft "post" des Benutzers überschreibe und versuche, die vollständig bearbeiteten Posts, die zuvor abgerufen wurden, zuzuweisen, wird die image-Eigenschaft von Post.js nicht richtig ausgefüllt. Es ist, als ob das ORM verhindert, dass die Bildsammlung von Post.js manuell zugewiesen wird.

Was mache ich falsch? Wie bevölkert man am besten tief verschachtelte Eins-zu-Viele-Assoziationen?

Bellow ich den gesamten Code eingefügt haben, die ich ausführen bin ....

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

Grüße,

Sávio Lucena

Antwort

11

Dies könnte eine alte Frage, aber es ist besser, eine Antwort zu haben, so sails.js Benutzer davon profitieren können.

hier Ihr Problem ist, dass, wenn Segel einen Datensatz (Innerhalb eines Arrays) gibt, die Schlüssel des Datensatzes, die Verbände entsprechen, sind in der Tat Getter/Setter, und es scheint, dass die Setter nicht, was Sie nicht erlaubt wollen. Sie können Object.getOwnPropertyDescriptor(user, 'posts') verwenden, um zu bestätigen. Also, was Sie tun müssen, um diese Eigenschaft zu überschreiben, wie Sie wollen, ist .toObject darauf zu nennen, (klonen Sie seine Eigenschaften über _.clone oder manuell Schleifen, aber Sie werden eine Menge Junk damit bekommen, so Bleiben Sie bei der .toObject), auf jeden Fall erhalten Sie ein neues Objekt mit den Eigenschaften, die Sie benötigen, und es gibt keine Einschränkung in, wie Sie es jetzt ändern.

So wird Ihr Code wie folgt aussehen:

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

Sie haben jede Post-ID-Objekt in Benutzer zu überschreiben .posts-Array. Für weitere Informationen überprüfen Sie diese Antwort https://stackoverflow.com/a/26452990/4261327.

+1

Jani, könnten Sie weiter in Ihrer Antwort graben? Ich habe versucht, alle Arten von Überschreiben, aber irgendwie, weil Bilder eine Viele-zu-Viele-Verbindung ist verhindert es, dass bestimmte Feld überschrieben werden. –