2013-09-02 3 views
0

J'utilise mongoose et j'ai deux modèles: Item et Hashtag.
Le modèle Hashtag ne doit contenir que le nom et le modèle d'élément doit contenir une liste de hashtags (représentés par des identifiants).
C'est ce que je l'ai fait:mongoose relation entre les modèles

var ItemSchema = new Schema({ 
    hashtags: [ { type: Schema.ObjectId, 'default': null, ref: 'Hashtag' } ], 
}); 

var HashtagSchema = new Schema({ 
    name: { type: String, 'default': '', trim: true }, 
    items: [{ type: Schema.ObjectId, ref: 'Page' }] 
}); 

Voici comment je tente de créer un élément:

var item = new Item({ 
     hashtags: ['a', 'b', 'c'] 
    }); 
    item.save(function (err, item) { 
     if (err) return res.json({ error: err }); 
     res.json(item); 
    }); 

Malheureusement je reçois cette erreur:

CastError: Cast to ObjectId failed for value "a,b,c" at path "hashtags" 

Comment puis-je résoudre ceci?

Répondre

2

Puisque vous utilisez references au lieu de subdocuments, vous devez créer les objets hashtag premier:

var tagnames = ['a','b','c']; 
var hashtags = {}; //for referencing quickly by name later 
for (var h in tagnames){ 
    var tag = new Hashtag({ 
     name: tagnames[h] 
    }); 
    tag.save(function (err, item) { 
     if (err) console.log('error:',err); 
     hashtags[item.name] = item; 
    }); 
} 

Une fois que vous avez les hashtags créés, vous pouvez les référencer ::

var item = new Item({ 
    hashtags: [hashtags.a._id,hashtags.b._id,hashtags.c._id] 
}); 
item.save(function (err, item) { 
    if (err) return res.json({ error: err }); 
    res.json(item); 
}); 

Ensuite, vous pouvez utiliser populate pour transformer automatiquement les ID d'objet en documents:

Item.find({}) 
    .populate('hashtags') 
    .exec(function (err, items) { 
     if (err) return handleError(err); 
     //items are populated with hashtags 
    }); 

Si vous faites simplement un simple marquage, alors subdocuments peut être un meilleur ajustement. Ils vous permettent de déclarer et de sauvegarder les documents enfants en une seule étape. Le compromis est que les sous-documents appartiennent exclusivement à leurs documents parents. Ce ne sont pas des références donc toute agrégation doit être faite manuellement.

+0

Est-il possible de lier les inserts de hashtags au modèle? Une sorte de contrainte? – Naor

+0

Oui, vous pouvez utiliser [subdocuments] (http://mongoosejs.com/docs/subdocs.html) si les hashtags peuvent appartenir à un seul élément. –

+0

Plus tard, je veux être en mesure de montrer tous les hashtags. Est-il possible d'ajouter quelque chose comme "before create" qui crée des hashtags si nécessaire et convertit les noms en ids? – Naor

Questions connexes