2011-08-12 5 views
8

J'ai parcouru l'API mongoose, et beaucoup de questions sur SO et sur google group, et je n'arrive toujours pas à comprendre la mise à jour des documents embarqués.Comment mettre à jour un document incorporé dans mongoose?

J'essaye de mettre à jour cet objet userListings particulier avec le contenu d'args.

for (var i = 0; i < req.user.userListings.length; i++) { 
    if (req.user.userListings[i].listingId == req.params.listingId) { 
     User.update({ 
      _id: req.user._id, 
      'userListings._id': req.user.userListings[i]._id 
     }, { 
      'userListings.isRead': args.isRead, 
      'userListings.isFavorite': args.isFavorite, 
      'userListings.isArchived': args.isArchived 
     }, function(err, user) { 
      res.send(user); 
     }); 
    } 
} 

Voici les schémas:

var userListingSchema = new mongoose.Schema({ 
    listingId: ObjectId, 
    isRead: { 
     type: Boolean, 
     default: true 
    }, 
    isFavorite: { 
     type: Boolean, 
     default: false 
    }, 
    isArchived: { 
     type: Boolean, 
     default: false 
    } 
}); 

var userSchema = new mongoose.Schema({ 
    userListings: [userListingSchema] 
}); 

Cette découverte ne fonctionne pas non plus, ce qui est probablement le premier numéro:

User.find({ 
    '_id': req.user._id, 
    'userListings._id': req.user.userListings[i]._id 
}, function(err, user) { 
    console.log(err ? err : user); 
}); 

qui retourne:

{ stack: [Getter/Setter], 
    arguments: [ 'path', undefined ], 
    type: 'non_object_property_call', 
    message: [Getter/Setter] } 

Cela devrait être l'équivalent du est appel client mongo:

db.users.find({'userListings._id': ObjectId("4e44850101fde3a3f3000002"), _id: ObjectId("4e4483912bb87f8ef2000212")}) 

Course à pied:

mongoose v1.8.1 
mongoose-auth v0.0.11 
node v0.4.10 

Répondre

6

lorsque vous avez déjà l'utilisateur, vous pouvez tout simplement faire quelque chose comme ceci:

var listing = req.user.userListings.id(req.params.listingId); 

listing.isRead = args.isRead; 
listing.isFavorite = args.isFavorite; 
listing.isArchived = args.isArchived; 

req.user.save(function (err) { 
    // ... 
}); 

que l'on trouve ici: http://mongoosejs.com/docs/subdocs.html

Finding a sub-document

Each document has an _id. DocumentArrays have a special id method for looking up a document by its _id.

var doc = parent.children.id(id); 

* * Avertissement * *

comme @zach a souligné, vous devez déclarer le schéma du sous-document avant le schéma du document pour pouvoir utiliser le id() méthode.

+2

Je reçois « TypeError: Object [object Object], [object Object], [object Object], [object Object] n'a pas de méthode « id ' – FrederickCook

+0

Est-ce un problème mongoose-auth? C'est là que req.user est assigné. – FrederickCook

+0

le docu mongoose dit: "DocumentArrays a un identifiant de méthode spécial qui filtre vos documents incorporés par leur propriété _id (chaque document incorporé en obtient un)". mais je n'ai pas essayé cela moi-même. – pkyeck

0

Est-ce juste un décalage sur les noms de variables? Vous avez user.userListings[i].listingId dans la boucle for mais user.userListings[i]._id dans le find Voulez-vous rechercher listingId ou _id?

0

Vous devez enregistrer l'objet parent et marquerModifié le document imbriqué.

Thats la façon dont nous le faisons

exports.update = function(req, res) { 
    if(req.body._id) { delete req.body._id; } 
    Profile.findById(req.params.id, function (err, profile) { 
    if (err) { return handleError(res, err); } 
    if(!profile) { return res.send(404); } 
    var updated = _.merge(profile, req.body); 
    updated.markModified('NestedObj'); 
    updated.save(function (err) { 
     if (err) { return handleError(res, err); } 
     return res.json(200, profile); 
    }); 
    }); 
}; 
Questions connexes