Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone-relational .set() method not updating related models

I've got backbone-relational working fairly well so far. I have relationships and reverse relationships well established (see below). When I initially call .fetch() on my Country model instance, the nominees array is parsed out into nominee models perfectly.

When I call .fetch() again later, however, these related models do not update, even though the nominee data has changed (e.g. the vote count has incremented). Essentially it seems that Backbone's .set() method understands relationships initially but not subsequently.

Country Model

var Country = Backbone.RelationalModel.extend({

    baseUrl : config.service.url + '/country',

    url : function () {
        return this.baseUrl;
    },

    relations : [
        {
            type : Backbone.HasMany,
            key : 'nominees',
            relatedModel : Nominee,
            collectionType : Nominee_Collection,
            reverseRelation : {
                key : 'country',
                includeInJSON : false
            }
        }
    ]
});

JSON Response on country.fetch()

{
  "entrant_count" : 1234,
  "vote_count" : 1234,
  "nominees" : [
    {
      "id" : 3,
      "name" : "John Doe",
      "vote_count" : 1,
      "user_can_vote" : true
    },
    {
      "id" : 4,
      "name" : "Marty McFly",
      "vote_count" : 2,
      "user_can_vote" : true
    }
  ]
}

Any help would be greatly appreciated, as always.

like image 255
Squirkle Avatar asked Nov 04 '22 12:11

Squirkle


1 Answers

So it appears that backbone-relational specifically forgoes updating relations automatically (see the updateRelations method), and simply emits a relational:change:nominees event which your models can target. If, however, you wish to programmatically update your related models, simply modify the updateRelations method as follows:

Backbone.RelationalModel.prototype.updateRelations = function( options ) {
    if ( this._isInitialized && !this.isLocked() ) {
        _.each( this._relations || [], function( rel ) {
            // Update from data in `rel.keySource` if set, or `rel.key` otherwise
            var val = this.attributes[ rel.keySource ] || this.attributes[ rel.key ];

            if ( rel.related !== val ) {
                this.trigger( 'relational:change:' + rel.key, this, val, options || {} );

                // automatically update related models
                _.each(val, function (data) {                           
                    var model = rel.related.get(data.id);
                    if (model) {
                        model.set(data);
                    } else {
                        rel.related.add(data);
                    }
                });
            }
        }, this );
    }
};

(Note that this does not handle deletion of models from a collection, only updates to existing models, and the addition of new models to a collection)

like image 86
Squirkle Avatar answered Nov 09 '22 04:11

Squirkle