platanus / angular-restmod

Rails inspired REST-API ORM for Angular
http://platanus.github.io/angular-restmod/
MIT License
1.18k stars 87 forks source link

$add silently ignores action if record is also in another collection. #387

Open werner291 opened 8 years ago

werner291 commented 8 years ago

Hello,

I ran into the situation where there were two models: "House" and "HouseGroup".

I fetched a list of houses using House.$search();, then took one of the records in that collection and $add-ed it to a HouseGroup (which has a hasMany relation to House).

The action fails silently because that house was already in the House collection.

This is the code in the library that causes it:

$add:` function(_obj, _idx) {
  Utils.assert(_obj.$type && _obj.$type === this.$type, 'Collection $add expects record of the same $type');

  return this.$action(function() {
    if(_obj.$position === undefined) { // <--- Here's the problem.
      if(_idx !== undefined) {
        this.splice(_idx, 0, _obj);
      } else {
        this.push(_obj);
      }
      _obj.$position = true; // use true for now, keeping position updated can be expensive
      this.$dispatch('after-add', [_obj]);
    }
  });
},

Proposed solution: allow records to be in multiple collections, or document why this is problematic and throw an exception instead of failing silently.

werner291 commented 7 years ago

Suggestion about why its' probably done this way:

Objects currently have a reference to the collection they're in. If you would make it possible to add it to multiple collections, the object would have references to multiple collections.

If one of those collections is no longer needed, it would normally be destroyed. However, there would still be a reference to that collection through the object that is in multiple collections, therefore resulting in that collection persisting, thus leading to a memory leak until refrences to all collections and all objects in those collections are dropped.