pruett
pruett

Reputation: 2121

Backbone model.destroy with MongoDB persistence

I'm new to Backbone and to MongoDB. I'm running into problems destroying models (that are backed by MongoDB). I believe it has something to do with the fact that a MongoDB "document" uses the abnormal _id attribute and is not wired up with Backbone by default. I've tried setting idAttribute: '_id' which does not seem to solve the issue.

A sample Mongo document looks like:

{
  _id: Object
    $oid: "527303e82f3504ba5bf4b21f"
  __proto__: Object
  feeling: "ok"
  location: "california"
  name: "Kevin"
}

models.coffee

class Models.Campaign extends Backbone.Model
  urlRoot: "http://localhost:4567/api/campaigns"
  # setting idAttribute: '_id' causes issues rendering the Backbone collection

controller.coffee

...
model.destroy() #=> only removes the item from the dom but does not make a DELETE request

Am I able to pass in an id to the destroy() function?

Does anyone have advise in how to properly wire up Backbone with MongoDB without having to monkeypatch a ton of built-in Backbone functions?

Upvotes: 0

Views: 294

Answers (1)

mu is too short
mu is too short

Reputation: 434585

I think you'll have an easier time if you add a parse to your model to sort out the confusing data you're getting from the server. You don't need or care about _id, you do care about $oid, and Backbone would prefer to work with an id property; you can sort out all three with a simple parse in your model like this:

parse: function(response) {
    var parsed = _(response).pick(
        'feeling',
        'location',
        'name'
    );
    parsed.id = response.$oid;
    return parsed;
}

Demo: http://jsfiddle.net/ambiguous/pn773/

You'd probably be fine if your parse modified response rather than making a semi-copy using _.pick and modifying that copy, however, parse doesn't technically own response so it would be rude to change it and there could be surprising side effects. Good habits, etc.

Then when Backbone tries to convert the server's data to a model, it will end up working with:

{
  id: "527303e82f3504ba5bf4b21f",
  feeling: "ok",
  location: "california",
  name: "Kevin"
}

and everyone should be happy:

  1. Backbone won't see the irrelevant _id.
  2. Backbone won't see $oid and you won't need to set idAttribute to anything special.
  3. Backbone will see an id like it expects and all the standard machinery will use the BSON ObjectId as the model's unique identifier.

The simple method should get you your DELETE /api/campaigns/527303e82f3504ba5bf4b21f request when you model.destroy().

Upvotes: 1

Related Questions