dist/model.js
function hasManySplice(i, n, added) {
  var owner = this.__owner__,
      desc = this.__desc__,
      inverse = desc.inverse,
      name = desc.name,
      removed,
      changes,
      i;

  added.forEach(function (o) {
    return checkAssociatedType(desc, o);
  });

  removed = _array2.default.prototype._splice.call(this, i, n, added);

  if (inverse && !this.__handlingInverse__) {
    removed.forEach(function (model) {
      model._inverseRemoved(inverse, owner);
    }, this);
    added.forEach(function (model) {
      model._inverseAdded(inverse, owner);
    }, this);
  }

  if (desc.owner && !loads.length) {
    changes = owner.ownChanges[name] = owner.ownChanges[name] || { added: [], removed: [] };

    removed.forEach(function (m) {
      if ((i = changes.added.indexOf(m)) !== -1) {
        changes.added.splice(i, 1);
      } else if (changes.removed.indexOf(m) === -1) {
        changes.removed.push(m);
      }
    });

    added.forEach(function (m) {
      if ((i = changes.removed.indexOf(m)) !== -1) {
        changes.removed.splice(i, 1);
      } else if (changes.added.indexOf(m) === -1) {
        changes.added.push(m);
      }
    });

    if (!changes.added.length && !changes.removed.length) {
      owner._clearChange(name);
    } else {
      owner._setChange(name, changes);
    }
  }

  return removed;
}
function hasManySplice(i, n, added) {
  var owner = this.__owner__,
      desc = this.__desc__,
      inverse = desc.inverse,
      name = desc.name,
      removed,
      changes,
      i;

  added.forEach(function (o) {
    return checkAssociatedType(desc, o);
  });

  removed = _array2.default.prototype._splice.call(this, i, n, added);

  if (inverse && !this.__handlingInverse__) {
    removed.forEach(function (model) {
      model._inverseRemoved(inverse, owner);
    }, this);
    added.forEach(function (model) {
      model._inverseAdded(inverse, owner);
    }, this);
  }

  if (desc.owner && !loads.length) {
    changes = owner.ownChanges[name] = owner.ownChanges[name] || { added: [], removed: [] };

    removed.forEach(function (m) {
      if ((i = changes.added.indexOf(m)) !== -1) {
        changes.added.splice(i, 1);
      } else if (changes.removed.indexOf(m) === -1) {
        changes.removed.push(m);
      }
    });

    added.forEach(function (m) {
      if ((i = changes.removed.indexOf(m)) !== -1) {
        changes.removed.splice(i, 1);
      } else if (changes.added.indexOf(m) === -1) {
        changes.added.push(m);
      }
    });

    if (!changes.added.length && !changes.removed.length) {
      owner._clearChange(name);
    } else {
      owner._setChange(name, changes);
    }
  }

  return removed;
}
Internal: The overridden `_splice` method used on `hasMany` arrays. This method syncs changes to the array to the inverse side of the association and maintains a list of changes made.