Ext version tested:
  • Ext 4.1 rev RC3
Description:
  • Maybe I am crazy but I think the generated getter success callback is using Function.call when it should be using Function.apply. Also the scope is not used on the second call to the generated getter if the scope provided in the options config.
Fix
Code:
Ext.define(App.override.data.association.HasOne', {
    override: 'Ext.data.association.HasOne',


    createGetter: function() {
        var me              = this,
            ownerModel      = me.ownerModel,
            associatedName  = me.associatedName,
            associatedModel = me.associatedModel,           
            foreignKey      = me.foreignKey,
            primaryKey      = me.primaryKey,
            instanceName    = me.instanceName;


        return function(options, scope) {
            options = options || {};


            var model = this,
                foreignKeyId = model.get(foreignKey),
                scope = options.scope || scope,
                success,
                instance,
                args;


            if (options.reload === true || model[instanceName] === undefined) {
                instance = Ext.ModelManager.create({}, associatedName);
                instance.set(primaryKey, foreignKeyId);


                if (typeof options == 'function') {
                    options = {
                        callback: options,
                        scope: scope || model
                    };
                }


                // Overwrite the success handler so we can assign the current instance
                success = options.success;
                options.success = function(rec){
                    model[instanceName] = rec;
                    if (success) {
                        success.apply(this, arguments);
                    }
                };


                associatedModel.load(foreignKeyId, options);
                // assign temporarily while we wait for data to return
                model[instanceName] = instance;
                return instance;
            } else {
                instance = model[instanceName];
                args = [instance];
                scope = scope || model;


                //TODO: We're duplicating the callback invokation code that the instance.load() call above
                //makes here - ought to be able to normalize this - perhaps by caching at the Model.load layer
                //instead of the association layer.
                Ext.callback(options, scope, args);
                Ext.callback(options.success, scope, args);
                Ext.callback(options.failure, scope, args);
                Ext.callback(options.callback, scope, args);


                return instance;
            }
        };
    }
});