node.js - node - socket io tutorial
Mangosta poblar después de guardar (7)
Solución que devuelve una promesa (sin devolución de llamada):
Usar documento # poblar
book.populate(''creator'').execPopulate();
// summary
doc.populate(options); // not executed
doc.populate(options).execPopulate() // executed, returns promise
Posible implementación
var populatedDoc = doc.populate(options).execPopulate();
var populatedDoc.then(doc => {
...
});
Lea sobre la población de documentos here .
No puedo completar de forma manual o automática el campo del creador en un objeto recién guardado ... la única forma en que puedo encontrar es volver a consultar los objetos que ya tengo y que odiaría hacer.
Esta es la configuración:
var userSchema = new mongoose.Schema({
name: String,
});
var User = db.model(''User'', userSchema);
var bookSchema = new mongoose.Schema({
_creator: { type: mongoose.Schema.Types.ObjectId, ref: ''User'' },
description: String,
});
var Book = db.model(''Book'', bookSchema);
Aquí es donde estoy tirando de mi cabello
var user = new User();
user.save(function(err) {
var book = new Book({
_creator: user,
});
book.save(function(err){
console.log(book._creator); // is just an object id
book._creator = user; // still only attaches the object id due to Mongoose magic
console.log(book._creator); // Again: is just an object id
// I really want book._creator to be a user without having to go back to the db ... any suggestions?
});
});
EDITAR: la última mangosta solucionó este problema y agregó funcionalidad de relleno, consulte la nueva respuesta aceptada.
Debería poder usar la función de llenado del modelo para hacer esto: http://mongoosejs.com/docs/api.html#model_Model.populate En el controlador de guardado para el libro, en lugar de:
book._creator = user;
harías algo como:
Book.populate(book, {path:"_creator"}, function(err, book) { ... });
Probablemente sea una respuesta demasiado tarde para ayudarlo, pero estuve atascado en esto recientemente, y podría ser útil para otros.
Desafortunadamente, este es un problema de larga duración con la mangosta, que creo que aún no está resuelto:
https://github.com/LearnBoost/mongoose/issues/570
Lo que puede hacer es escribir su propio getter / setter (y establecer _customer
real en una propiedad separada) para esto. Por ejemplo:
var get_creator = function(val) {
if (this.hasOwnProperty( "__creator" )) {
return this.__creator;
}
return val;
};
var set_creator = function(val) {
this.__creator = val;
return val;
};
var bookSchema = new mongoose.Schema({
_creator: {
type: mongoose.Schema.Types.ObjectId,
ref: ''User'',
get: get_creator,
set: set_creator
},
description: String,
});
NOTA: No lo .populate
y podría funcionar de manera extraña con .populate
y al establecer la identificación pura.
En caso de que alguien todavía esté buscando esto.
Mongoose 3.6 ha introducido una gran cantidad de características geniales para poblar:
book.populate(''_creator'', function(err) {
console.log(book._creator);
});
o:
Book.populate(book, ''_creator'', function(err) {
console.log(book._creator);
});
vea más en: https://github.com/LearnBoost/mongoose/wiki/3.6-Release-Notes#population
Pero de esta manera aún consultas al usuario nuevamente.
Un pequeño truco para lograrlo sin consultas adicionales sería:
book = book.toObject();
book._creator = user;
La solución para mí fue usar execPopulate
, como tal
const t = new MyModel(value)
return t.save().then(t => t.populate(''my-path'').execPopulate())
Probablemente sth. me gusta
Book.createAsync(bookToSave).then((savedBook) => savedBook.populateAsync("creator"));
Sería la forma más agradable y menos problemática de hacer que esto funcione (usando las promesas de Bluebird).
Solo para elaborar y dar otro ejemplo, ya que me ayudó. Esto podría ayudar a aquellos que quieran recuperar objetos parcialmente poblados después de guardar. El método es ligeramente diferente también. Pasé más de una o dos horas buscando la forma correcta de hacerlo.
post.save(function(err) {
if (err) {
return res.json(500, {
error: ''Cannot save the post''
});
}
post.populate(''group'', ''name'').populate({
path: ''wallUser'',
select: ''name picture''
}, function(err, doc) {
res.json(doc);
});
});