2012-10-23 16 views
15

Ich bin Neuling zu MongoDB und Backbone, also versuche ich, sie zu verstehen, aber es ist schwer. Ich habe ein großes, großes Problem: Ich kann nicht verstehen, wie Attribute in Backbone.Model manipuliert werden, um in Views nur das zu verwenden, was ich brauche. Speziellere - Ich habe ein Modell:MongoError: kann _id eines Dokuments nicht ändern

window.User = Backbone.Model.extend({ 

    urlRoot:"/user", 
    idAttribute: "_id", 

    defaults: { 
     _id: null, 
     name: "", 
     email: "[email protected]" 
    } 
}); 

window.UserCollection = Backbone.Collection.extend({ 
    model: User, 

    url: "user/:id" 
}); 

Und ich habe eine Ansicht:

beforeSave: function(){ 
    var self = this; 
    var check = this.model.validateAll(); 
    if (check.isValid === false) { 
     utils.displayValidationErrors(check.messages); 
     return false; 
    } 
    this.saveUser(); 
    return false; 
}, 

saveUser: function(){ 
    var self = this; 
    console.log('before save'); 
    this.model.save(null, { 
     success: function(model){ 
      self.render(); 
      app.navigate('user/' + model.id, false); 
      utils.showAlert('Success!', 'User saved successfully', 'alert-success'); 
     }, 
     error: function(){ 
      utils.showAlert('Error', 'An error occurred while trying to save this item', 'alert-error'); 
     } 
    }); 
} 

Ich habe zu verwenden 'setzen' Methode Whit Daten aus beliebigen Bereichen mit Ausnahme von '_id', so muss es sein smth wie:

{"name": "Foo", "email": "[email protected]"} 

Aber jedes Mal, hängt nicht davon ab, was ich es tun senden

012.351.
{**"_id": "5083e4a7f4c0c4e270000001"**, "name": "Foo", "email": "[email protected]"} 

und dieser Fehler vom Server:

MongoError: cannot change _id of a document old:{ _id: ObjectId('5083e4a7f4c0c4e270000001'), name: "Foo" } new:{ _id: "5083e4a7f4c0c4e270000001", name: "Bar", email: "[email protected]" }

Github Link: https://github.com/pruntoff/habo

Vielen Dank im Voraus!

+0

Wenn Sie 'model.save nennen()' ist ein POST durchgeführt oder eine PUT werden? – InPursuit

+0

es ist PUT durchgeführt. 'app.get ('/ user /: id', usr.findById); app.put ('/ user /: id', usr.updateUser); ' – Pruntoff

+0

Wenn der Backbone beim Aufruf von' save' einen PUT ausführt, sollte das IDAttribute des Modells (_id in Ihrem Fall) nicht gesendet werden. Können Sie 'isNew()' auf Ihrem Modell vor 'save()' aufrufen und sicherstellen, dass es 'false' zurückgibt? Überprüfen Sie außerdem, dass 'this.model.id' vor dem Aufruf von' save() 'nicht null oder undefiniert ist. – InPursuit

Antwort

6

Aus dem Blick auf Ihren Mongo-Fehler, ist das Problem nicht mit Mongo, es tut nur, was es tun soll. Es hatte ein Objekt mit _id von ObjectId Typ: ObjectId ('xxx') und jetzt versuchen Sie, dieses Objekt zu ändern, um eine _id eines String-Typs (_id: "5083e4a7f4c0c4e270000001") zu haben, und das Mongo anscheinend nicht mag.

Die Frage ist also: Warum hatte das Objekt überhaupt eine ID vom Typ ObjectId? Wie hast du es zum ersten Mal gemacht? Wenn Sie eine andere Methode verwendet haben, um es zu initialisieren (ich rate serverseitig), sollten Sie den ID-Typ als String festlegen, damit er mit dem aus der Skriptbibliothek übereinstimmt. Wenn Sie möchten, dass es eine ObjectId bleibt, müssen Sie die Zeichenfolge, die von Ihrem Skript stammt, in eine ObjectId konvertieren, bevor Sie sie in Mongo speichern.

HTH.

+0

Vielen Dank für Ihre Antwort! Ich sehe dieses Problem, aber es gibt auch ein Problem in MongoDB, wenn ich richtig verstehe, sagt Mongo Docs: * Das Feld _id ist unveränderlich.Wenn Sie versuchen, den Wert eines Updates zu ändern, erhalten Sie einen "Mod bei _id not allowed" -Fehler von getLastError. * Ich denke also, dass ich das Senden von _id attr im Modell ablehnen muss, aber das Modell muss es haben. In allem, können Sie mir sagen, wie Zeichenfolge in ObjectId-Objekt zu konvertieren, wenn ich JSON-Daten im Modell Figur? Fall Anfrage an den Server hat JSON-Objekt mit _id Zeichenfolge, und ich kann es nicht auf der Serverseite manipulieren. – Pruntoff

+0

Ich denke, es ist in Ordnung, dieses Feld zu senden, wenn Sie ein Update durchführen, sondern als eine Kennung, um das Objekt zu finden, das Sie ändern möchten. Ich habe das Gefühl, dass, wenn Sie die ID im selben Format (ObjectId) senden, Mongo nicht widersprechen wird (da es nicht geändert wird). Ich weiß nicht, wie man von String zu ObjectId konvertiert, da ich nicht weiß, welche Sprache Sie verwenden, aber die Frage bleibt: Wie hat es überhaupt eine ObjectId bekommen? Woher kam das ursprüngliche Objekt? – TheZuck

+0

Ich nehme das Problem, du hattest recht, es dreht sich alles um Formatierung. Beantworten Sie Ihre Fragen: ObjectId wird automatisch von mongoDb an erster Stelle gesetzt, wenn ich einige JSON-Daten einfüge. Um das Problem zu lösen, ich brauche keinen Gebrauch mongoDB mit Mungo statt nur mondoDB Treiber I '.Types.ObjectId verwenden;'. Wenn ich nicht falsch mongo Treiber habe keine Methoden, um Daten in ObjectId Daten zu konvertieren. ! :(Vielen Dank für Ihre Hilfe – Pruntoff

5

MongoDB schafft _id als ObjectID, aber abrufen nicht _id als ObjectID.

Ob diese Inkonsistenz "korrektes Verhalten" ist oder nicht, ist für die meisten MongoDB-Benutzer sicherlich eine ärgerliche Überraschung.

Sie beheben können es mit:

if (this._id && (typeof(this._id) === 'string')) { 
    log('Fixing id') 
    this._id = mongodb.ObjectID.createFromHexString(this._id) 
} 

MongoDB can't update document because _id is string, not ObjectId Siehe

+1

Alternativ können Sie 'var BSON = mongodb.BSONPure' definieren und diese Funktion verwenden:' this._id = new BSON.ObjectID (this._id); ' –

Verwandte Themen