Fix issues with unregistering nested records. #863

wants to merge 6 commits into

3 participants


After upgrading to 1.9, we started having issues with the datastore and nested records. I was able to trace this back to commits 0b5b2db and 62d599a. I've made some changes here that appear to improve the situation , but I haven't completely fixed the problem and haven't been having much luck finding the problem.

I made a gist ( with a small app that exhibits the problem.

I'd like to get some insight into what might be causing the remaining issues.

Greg Fairbanks Fix issues with unregistering nested records.
There were a couple of issues with unregistering nested records:

1) SC.ChildArray did not unregister nested records at all, so toMany
relations with nested records did not work properly.
2) When a child was unregistered from its parent, that did not propagate
to children of the child, leading to problems when nesting was several
levels deep.
3) There were two additional caches that were not being cleared when the
nested record was unregistered.
SproutCore member
Greg Fairbanks added some commits Nov 19, 2012
Greg Fairbanks Fix calculations for (un)registering ChildArray records.
The previous commit incorrectly calculated which records to unregister
and register. All items after the passed in index need to be unregistered,
then all the new items should be registered, followed by the existing items
that were previously unregistered.
Greg Fairbanks Fix drag and drop handling for nested records.
If the item that is dragged is a nested record, special handling is needed
because the data hash will be removed when the record is unregistered. We
need to read the data hash so it doesn't get lost.
SproutCore member

Hi Greg, I sort of see what is happening. Your example code (thanks it helps a lot!) is creating App.BottomLevel and App.MidLevel as SC.Records and then adding them to the nested record relationships. I haven't figured it out entirely, but since nested records are really just convenience wrappers around Objects, I think you should be creating them as such.

var midlevel = { bProperty: 'BBB' };
var bottomlevel = { cProperty: 'CCC' };
midlevel.bottomLevel = bottomlevel;

Instead of:

var midlevel =, { bProperty: 'BBB' });
var bottomlevel =, { cProperty: 'CCC' });
midlevel.set('bottomLevel', bottomlevel);

Doing it that way solves one problem that I found, which is that attempting to get the nested record property ends up creating a new Record with a default internal id, because the previously assigned manually created record doesn't have an id. You can see this using the gist code, because there are 4 MidLevel records in the store on launch instead of two. Two of which don't have ids (manually created) and two that do (automatically created and used).

But it'll take more time to figure out why removing a midlevel object doesn't remove it from the store, which is why adding a new midlevel object doesn't seem to work correctly (it generates an internal id, finds that a record with a matching id is in the store and uses it).

I'll keep looking at it when I can. I'm also unsure of what the proper CRUD for nested records really should be. Actually, now that I think of it, the way you are creating them should work...

SproutCore member

Oops.. I wrote the above thinking I was replying on an issue and forgot about your proposed changes. I will look at how that solves the problem.

SproutCore member

As you've probably seen, it looks like a refactor of nested records which should alleviate all these weird behaviours is in the works. While that is in progress, I thought I would pull in your commits in this branch (except maybe the CollectionView patch), but when I ran the full suite of datastore unit tests, there were a number that failed. I didn't look at them, but are you able to figure out what is happening? I can't bring this in unless all the tests (save 1 that I know is failing currently)

About the CollectionView patch, it's so special case and I'm really worried about it getting forgotten inside the view. I wonder if we can't manage without it or separate it out more so that those who need it can find it.


Greg Fairbanks added some commits Dec 20, 2012
Greg Fairbanks Further changes to unregister child records when a record is unloaded. 85fe1fd
Greg Fairbanks Propagate status changes to child records.
Since nested records are now being properly unregistered, the status of
nested records was getting stale, leading to exceptions because the status
was still set to SC.Record.EMPTY.
Greg Fairbanks Modified unregisterChildFromParent so it can safely be called on any
storeKey, even if it is not a child record.
@publickeating publickeating added a commit that closed this pull request Aug 30, 2014
@publickeating publickeating Closes #863 Fixes merge conflicts and removes extra cycles of calling…
… `unloadRecord` on children and `unregisterChildFromParent` on the parent.
SproutCore member

Rebased this onto master and worked through the conflicts. I made some minor changes to the functionality of unloadRecord, which should work better. The only piece I didn't carry over was the piece in SC.CollectionView. I'm not sure about that one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment