2012-10-23 17 views
15

Sono novizio di MongoDB e Backbone, quindi cerco di capirli, ma è difficile. Ho un grosso problema: non riesco a capire come manipolare gli attributi in Backbone.Model per utilizzare solo in Views ciò di cui ho bisogno. Più specifica - Ho un modello :MongoError: impossibile cambiare _id di un documento

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

e ho un Visualizza:

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

devo usare i dati metodo di Pentecoste 'put' da tutti i campi ad eccezione di '_id', quindi deve essere smth come:

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

Ma ogni volta, non dipende da quello che faccio che invia

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

e questo errore da 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

Grazie in anticipo!

+0

Quando si chiama 'model.save()' è un post in corso di esecuzione o di un PUT? – InPursuit

+0

eseguito PUT. 'app.get ('/ utente /: id', usr.findById); app.put ('/ utente /: id', usr.updateUser); ' – Pruntoff

+0

Se il backbone esegue un PUT quando si chiama' save', l'idAttribute del modello (_id nel tuo caso) non deve essere inviato. Puoi chiamare 'isNew()' sul tuo modello prima di 'save()' e verificare che restituisca 'false'? Verifica anche che 'this.model.id' non sia nullo o indefinito prima di chiamare' save() ' – InPursuit

risposta

6

Dal punto di vista del tuo errore mongo, il problema non è con mongo, sta solo facendo ciò che dovrebbe fare. Aveva un oggetto con _id del tipo ObjectId: ObjectId ('xxx') e ora stai provando a cambiare quell'oggetto per avere un _id di un tipo String (_id: "5083e4a7f4c0c4e270000001") e che a quanto pare a Mongo non piace.

Quindi, la domanda è: perché l'oggetto ha un id di tipo ObjectId in primo luogo? Come l'hai impostato la prima volta? Se hai usato un altro metodo per inizializzarlo (sto supponendo lato server), dovresti impostare il tipo id come stringa in modo che sia uguale a quello proveniente dalla tua libreria di script. Se vuoi che rimanga un ObjectId, dovrai convertire la stringa proveniente dallo script in un ObjectId prima di salvarla in Mongo.

HTH.

+0

Grazie mille per la tua risposta! Vedo quel problema, ma c'è anche un problema in MongoDB, se capisco bene, mongo docs dice: * Il campo _id è immutabile.Se provate a cambiare il suo valore su un aggiornamento, otterrete un errore "Mod on _id not allowed" da getLastError. * Quindi penso di dover eliminare l'invio di _id attr nel modello, ma il modello deve averlo. In totale, puoi dirmi come convertire la stringa in oggetto ObjectId quando indico i dati JSON nel modello? la richiesta del caso al server ha un oggetto JSON con _id stringa e non posso manipolarlo sul lato server. – Pruntoff

+0

Penso che sia giusto inviare quel campo quando si fa un aggiornamento ma come identificatore per trovare l'oggetto che si desidera modificare. Ho la sensazione che se si invia l'id nello stesso formato (ObjectId), Mongo non obietterà (poiché non viene modificato). Non so come convertire da String a ObjectId in quanto non so quale lingua stai usando, ma rimane comunque la domanda: come ha ottenuto un ObjectId in primo luogo? da dove viene l'oggetto originale? – TheZuck

+0

Prendo il problema, avevi ragione, è tutto sulla formazione. Risposta alle tue domande: ObjectId viene automaticamente inserito in primo luogo da mongoDb quando inserisco alcuni dati JSON. Per risolvere il problema non ho bisogno di usare mongoDB con mangusta invece solo driver mondoDB uso '.Types.ObjectId;'. Se non confondo i driver di mongo non ho metodi per convertire i dati in dati ObjectId. :(Grazie mille per il tuo aiuto! – Pruntoff

5

MongoDB crea _id come ObjectID, ma non recuperare _id come ObjectID.

Se questa incoerenza è "comportamento corretto" o meno, è sicuramente una sorpresa fastidiosa per la maggior parte degli utenti MongoDB.

È possibile risolvere il problema con:

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

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

+1

In alternativa, puoi definire 'var BSON = mongodb.BSONPure' e usare questa funzione:' this._id = new BSON.ObjectID (this._id); ' –

Problemi correlati