    /** * **This class is never created directly. It should be constructed through associations in `Ext.data.Model`.** * * This is a specialized version of `Ext.data.schema.ManyToOne` that declares a relationship between a single  * entity type and a single related entities. The relationship can be declared as a keyed or keyless relationship. * *     // Keyed *     Ext.define('User', { *         extend: 'Ext.data.Model', *         fields: ['id', 'name', { *             name: 'userInfoId', *             reference: { *                 type: 'UserInfo', *                 unique: true *             } *         }] *     }); * *     Ext.define('UserInfo', { *         extend: 'Ext.data.Model', *         fields: ['id', 'secretKey'] *     }); * *     // Keyless *     Ext.define('User', { *         extend: 'Ext.data.Model', *         fields: ['id', 'name'], *         hasOne: 'UserInfo' *     }); * *     Ext.define('Ticket', { *         extend: 'Ext.data.Model', *         fields: ['id', 'secretKey'] *     }); * *     // Generated methods *     var user = new User(); *     user.getUserInfo(); *     user.setUserInfo(); *      *     var info = new UserInfo(); *     info.getUser(); *     info.setUser(); *      * *     var ticket = new Ticket(); *     ticket.setCustomer(customer); *     console.log(ticket.getCustomer()); // The customer object * * By declaring a keyed relationship, extra functionality is gained that maintains * the key field in the model as changes are made to the association.  *  * For available configuration options, see {@link Ext.data.schema.Reference}. * Each record type will have a {@link Ext.data.schema.Association#recordGetter getter} and {@link Ext.data.schema.Association#recordSetter setter}. */Ext.define('Ext.data.schema.OneToOne', {    extend: 'Ext.data.schema.Association',     isOneToOne: true,     isToOne: true,     kind: 'one-to-one',     Left: Ext.define(null, {        extend: 'Ext.data.schema.Role',         onDrop: function(rightRecord, session) {            var leftRecord = this.getAssociatedItem(rightRecord);            rightRecord[this.getInstanceName()] = null;            if (leftRecord) {                leftRecord[this.inverse.getInstanceName()] = null;            }        },         onIdChanged: function(rightRecord, oldId, newId) {            var leftRecord = this.getAssociatedItem(rightRecord),                fieldName = this.association.getFieldName();             if (!rightRecord.session && leftRecord && fieldName) {                leftRecord.set(fieldName, newId);            }        },         createGetter: function() {            var me = this;            return function () {                // 'this' refers to the Model instance inside this function                 return me.doGet(this);            };        },         createSetter: function () {            var me = this;            return function (value) {                // 'this' refers to the Model instance inside this function                 return me.doSet(this, value);            };        },         doGet: function (rightRecord) {            // Consider the Department entity with a managerId to a User entity. The             // Department is on the left (the FK holder's side) so we are implementing the             // guts of the getManagerDepartment method we place on the User entity. Since             // we represent the "managerDepartment" role and as such our goal is to get a             // Department instance, we start that from the User (rightRecord). Sadly that             // record has no FK back to us.              var instanceName = this.getInstanceName(), // ex "managerDepartment"                 ret = rightRecord[instanceName],                session = rightRecord.session;             if (!ret && session) {                // @TODO: session - we'll cache the result on the record as always                 // but to get it we must ask the session             }             return ret || null;        },         doSet: function (rightRecord, leftRecord) {            // We are the guts of the setManagerDepartment method we place on the User             // entity. Our goal here is to establish the relationship between the new             // Department (leftRecord) and the User (rightRecord).              var instanceName = this.getInstanceName(), // ex "managerDepartment"                 ret = rightRecord[instanceName],                inverseSetter = this.inverse.setterName;  // setManager for Department              if (ret !== leftRecord) {                rightRecord[instanceName] = leftRecord;                 if (inverseSetter) {                    // Because the FK is owned by the inverse record, we delegate the                     // majority of work to its setter. We've already locked in the only                     // thing we keep on this side so we won't recurse back-and-forth.                     leftRecord[inverseSetter](rightRecord);                }                rightRecord.onAssociatedRecordSet(leftRecord, this);            }             return ret;        },         read: function(rightRecord, node, fromReader, readOptions) {            var me = this,                leftRecords = me.callParent([rightRecord, node, fromReader, readOptions]),                leftRecord;             if (leftRecords) {                leftRecord = leftRecords[0];                if (leftRecord) {                    leftRecord[me.inverse.getInstanceName()] = rightRecord;                     rightRecord[me.getInstanceName()] = leftRecord;                    // Inline associations should *not* arrive on the "data" object:                     delete rightRecord.data[me.role];                }            }        }    }),     Right: Ext.define(null, {        extend: 'Ext.data.schema.Role',         left: false,        side: 'right',                createGetter: function() {            // As the target of the FK (say "manager" for the Department entity) this             // getter is responsible for getting the entity referenced by the FK value.             var me = this;             return function (options, scope) {                // 'this' refers to the Model instance inside this function                 return me.doGetFK(this, options, scope);            };        },                createSetter: function() {            var me = this;             return function(value, options, scope) {                // 'this' refers to the Model instance inside this function                 return me.doSetFK(this, value, options, scope);            };        },         onDrop: function(leftRecord, session) {            var me = this,                field = me.association.field,                rightRecord = me.getAssociatedItem(leftRecord),                id;             if (me.inverse.owner) {                if (session && field) {                    id = leftRecord.get(field.name);                    if (id || id === 0) {                        rightRecord = session.getEntry(me.cls, id).record;                        if (rightRecord) {                            rightRecord.drop();                        }                    }                } else {                    if (rightRecord) {                        rightRecord.drop();                    }                }            }                         if (field) {                leftRecord.set(field.name, null);            }            leftRecord[me.getInstanceName()] = null;            if (rightRecord) {                rightRecord[me.inverse.getInstanceName()] = null;            }        },         onValueChange: function(leftRecord, session, newValue) {            // Important to get the record before changing the key.             var me = this,                rightRecord = leftRecord[me.getOldInstanceName()] || me.getAssociatedItem(leftRecord),                hasNewValue = newValue || newValue === 0,                instanceName = me.getInstanceName(),                cls = me.cls;             leftRecord.changingKey = true;            me.doSetFK(leftRecord, newValue);            if (!hasNewValue) {                leftRecord[instanceName] = null;            } else if (session && cls) {                // Setting to undefined is important so that we can load the record later.                 leftRecord[instanceName] = session.peekRecord(cls, newValue) || undefined;            }            if (me.inverse.owner && rightRecord) {                me.association.schema.queueKeyCheck(rightRecord, me);            }            leftRecord.changingKey = false;        },         checkKeyForDrop: function(rightRecord) {            var leftRecord = this.inverse.getAssociatedItem(rightRecord);            if (!leftRecord) {                // Not reassigned to another parent                 rightRecord.drop();            }        },                read: function(leftRecord, node, fromReader, readOptions) {            var me = this,                rightRecords = me.callParent([leftRecord, node, fromReader, readOptions]),                rightRecord, field, fieldName, session,                 refs, id, oldId, setKey, data;             if (rightRecords) {                rightRecord = rightRecords[0];                field = me.association.field;                if (field) {                    fieldName = field.name;                }                session = leftRecord.session;                data = leftRecord.data;                if (rightRecord) {                     if (session) {                        refs = session.getRefs(rightRecord, this.inverse, true);                        // If we have an existing reference in the session, or we don't and the data is                         // undefined, allow the nested load to go ahead                         setKey = (refs && refs[leftRecord.id]) || (data[fieldName] === undefined);                    } else {                        setKey = true;                    }                                         if (setKey) {                        // We want to poke the inferred key onto record if it exists, but we don't                         // want to mess with the dirty or modified state of the record.                         if (field) {                            oldId = data[fieldName];                            id = rightRecord.id;                            if (oldId !== id) {                                data[fieldName] = id;                                if (session) {                                    session.updateReference(leftRecord, field, id, oldId);                                }                            }                        }                        rightRecord[me.inverse.getInstanceName()] = leftRecord;                        leftRecord[me.getInstanceName()] = rightRecord;                    }                    // Inline associations should *not* arrive on the "data" object:                     delete data[me.role];                }            }        }    })});