From d3f37c31da1bcee00f1ac4c83453eb38a0f45e75 Mon Sep 17 00:00:00 2001 From: Jamie White Date: Fri, 17 Jul 2015 18:51:39 +0100 Subject: [PATCH] [BUGFIX release] Guard against isDestroyed in ManyArray.flushCanonical Addresses #3084 --- addon/-private/system/many-array.js | 6 +- .../relationships/has-many-test.js | 62 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/addon/-private/system/many-array.js b/addon/-private/system/many-array.js index c3d0b0b6f7f..69b9bcb5a45 100644 --- a/addon/-private/system/many-array.js +++ b/addon/-private/system/many-array.js @@ -4,6 +4,7 @@ import Ember from 'ember'; import { assert } from "ember-data/-private/debug"; import { PromiseArray } from "ember-data/-private/system/promise-proxies"; +import { _objectIsAlive } from "ember-data/-private/system/store/common"; var get = Ember.get; var set = Ember.set; @@ -84,7 +85,10 @@ export default Ember.Object.extend(Ember.MutableArray, Ember.Evented, { toSet = toSet.concat(newRecords); var oldLength = this.length; this.arrayContentWillChange(0, this.length, toSet.length); - this.set('length', toSet.length); + // It’s possible the parent side of the relationship may have been unloaded by this point + if (_objectIsAlive(this)) { + this.set('length', toSet.length); + } this.currentState = toSet; this.arrayContentDidChange(0, oldLength, this.length); //TODO Figure out to notify only on additions and maybe only if unloaded diff --git a/tests/integration/relationships/has-many-test.js b/tests/integration/relationships/has-many-test.js index 31ffb6506a3..a0794adc833 100644 --- a/tests/integration/relationships/has-many-test.js +++ b/tests/integration/relationships/has-many-test.js @@ -2700,3 +2700,65 @@ test("PromiseArray proxies createRecord to its ManyArray before the hasMany is l }); }); }); + +test("unloading and reloading a record with hasMany relationship - #3084", function(assert) { + var user; + var message; + + run(function() { + env.store.push({ + data: [{ + type: 'user', + id: 'user-1', + attributes: { + name: 'Adolfo Builes' + }, + relationships: { + messages: { + data: [ + { type: 'message', id: 'message-1' } + ] + } + } + }, { + type: 'message', + id: 'message-1' + }] + }); + + user = env.store.peekRecord('user', 'user-1'); + message = env.store.peekRecord('message', 'message-1'); + + assert.equal(get(user, 'messages.firstObject.id'), 'message-1'); + assert.equal(get(message, 'user.id'), 'user-1'); + }); + + run(function() { + env.store.unloadRecord(user); + }); + + run(function() { + // The record is resurrected for some reason. + env.store.push({ + data: [{ + type: 'user', + id: 'user-1', + attributes: { + name: 'Adolfo Builes' + }, + relationships: { + messages: { + data: [ + { type: 'message', id: 'message-1' } + ] + } + } + }] + }); + + user = env.store.peekRecord('user', 'user-1'); + + assert.equal(get(user, 'messages.firstObject.id'), 'message-1'); + assert.equal(get(message, 'user.id'), 'user-1'); + }); +});