3

Is it possible to make Backbone.js work with compound keys?

Id est, instead of setting id or idAttributemodel to a specific value, I want to know Backbone.js that I will be using more than one property. In such a way, every RESTful call would be made sending those two parameters to identify the object we're talking about.

For the sake of an example, let's say that I want to update a person's debt to a specific person, and the model is:

Borrower (borrowerId, name, ...)
Lender (lenderId, name, ...)
Debt (borrowerId, lenderId, debtAmount)

So, I now want to make Backbone.js update/delete a debt object. How can I make it work with the compound key (borrowerId, lenderId)?

Will Hartung
  • 115,893
  • 19
  • 128
  • 203
Alpha
  • 7,586
  • 8
  • 59
  • 92

2 Answers2

4

You could override the url() implementation of your model, as suggested in Backbone's documentation:

var Debt = Backbone.Model.extend({
  url: function() {
    var base = /* your base URL here */;
    if (this.isNew()) return base;
    return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.get("borrowerId")+"_"+this.get("lenderId"));
  }
});

The above code would result in URLs of the form baseURL/borrowerId_lenderId. Note that you may want to take a collections base URL into account when constructing the model's URL.

Julian D.
  • 5,464
  • 1
  • 25
  • 35
  • 1
    Thanks! How would you set up the `id` or `idAttribute` values to follow this convention as well? – Alpha Feb 24 '12 at 17:56
  • 1
    It seems overriding url() isn't enough. I had to also override parse() to generate the fake id from the compound keys: http://stackoverflow.com/questions/15199615/backbone-does-post-instead-of-put-on-updates-when-composite-key-is-used Then it works perfectly. – geon Nov 19 '13 at 15:41
  • 1
    The follow-up question re: `id` or `idAttribute` is that you can configure your model to use a composite key using `idAttribute: ["borrowerId", "lenderId"]`. – mikebridge Jun 08 '15 at 22:02
  • I don't think `idAttribute: ["borrowerId", "lenderId"]` will work. This will cause Backbonen to always issue `create`(POST) instead of `update`(PUT) messages cause this `this.isNew()` will always return true. – Spig Feb 09 '16 at 15:43
  • Another props will work: `idAttributes`. It's composite so another S just fine. – Abdillah Jan 23 '17 at 15:24
0

You need to override the URL function and the modelid function on a collection. The URL by default only knows what to do with a single attribute so you need a way to map it.

A collection uses a dictionary to find elements during a get. There is a modelId function that will covert a model into a strong that represents the key to use in the dictionary. For compounds you make it return '' + id1 + '-' + id2 or similar.

shimpossible
  • 356
  • 2
  • 5