sproutcore/sproutcore — pull request #1178 by dcporter (2014-02-21 15:43:45+00:00)
Title: Improves nested store handling of record loading. Includes unit tests.

SC.NestedStore#lockOnRead, which defaults to YES, is intended to safely silo nested stores from each other. However, by overaggressively locking records even when they’re not yet loaded, it causes problems even when operating on its own. If a record is retrieved from a solo nested store (e.g. by following a toOne relationship) and read-and-locked while loading (e.g. by being bound to a view), one of two bugs is triggered when the record finishes loading:
- If the nested store has no other changes, then the load triggers a full reset of the nested store, but fails to notify the nested-store record that it has loaded. The record’s status is stranded at BUSY_LOADING, and any cached attributes stay null. (If this were the only issue, it could be solvable by changing the `reset` call to `discardChanges`.)
- If any other (unrelated) records have been dirtied in the nested store, it throws a CHAIN_CONFLICT_ERROR, even though the record being loaded is conflict-free.

This commit solves the first problem by preventing lockOnRead from locking nested-store records when they are read in EMPTY or BUSY_LOADING states; this prevents the record from locking before there is anything to lock. It solves the second problem by modifying the behavior of SC.Store#_notifyRecordPropertyChange to switch behavior solely based on the chained record’s editable (locked) state, rather than worrying about record status or store-wide dirtiness.