PDA

View Full Version : Memory proxy doesn't fetch correct record for belongsTo association



kleinsch
22 Aug 2011, 11:24 AM
Sencha Touch version tested:

1.1.0


only default ext-all.css


Platform tested against:

Chrome
iOS4


Description:

When using a memory proxy, finding a belongsTo association returns the first row, not the correct record. This appears to be because in Ext.data.MemoryProxy read() there's nothing checking for operation.id and sending back the correct record, instead it sends back all records. The code that calls this takes resultSet[0], so it always gets the first record.


Test Case:




Ext.ns('MyApp');

MyApp.Product = Ext.regModel('Product', {
fields: [
{name: 'id', type: 'int'},
{name: 'user_id', type: 'int'},
{name: 'name', type: 'string'}
],


belongsTo: [
{model: 'User', name: 'user'}
],

proxy: {
type: 'memory',
id: 'user'
}
});


MyApp.User = Ext.regModel('User', {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'}
],


associations: [
{type: 'hasMany', model: 'Product', name: 'products'}
],

proxy: {
type: 'memory',
id: 'product'
}
});


Ext.regStore('User', {
model: "User",
data: [
{
id: 1,
name: "nick"
},
{
id: 2,
name: "jim"
}
]

});


Ext.regStore('Product', {
model: "Product",
data: [
{
id: 1,
user_id: 1,
name: "myProduct"
},
{
id: 2,
user_id: 1,
name: "myProduct2"
},
{
id: 3,
user_id: 2,
name: "myProduct3"
},
{
id: 4,
user_id: 2,
name: "myProduct4"
}
]
});


var product = Ext.getStore('Product').getById(4);
console.log('Testing finding product (should be myProduct4): ' + product.data.name);
product.getUser(function(user) {
console.log('Testing getting product\'s user via getUser (should be jim): ' + user.data.name);
});


new Ext.Application({
launch: function() {
new Ext.Panel({
fullscreen: true,
items: [
{html: 'hello world'}
]
});
}
});



Steps to reproduce the problem:

Run provided test case, examine console output


The result that was expected:

[Console output] Testing getting product's user via getUser (should be jim): jim


The result that occurs instead:

[Console output] Testing getting product's user via getUser (should be jim): nick


Possible Fix:

Hacked this together to fix the problem temporarily, but it's probably not optimal, as I don't understand the underlying architecture completely.


Ext.data.MemoryProxy.override({
read: function(operation, callback, scope) {
var reader = this.getReader(),
result = reader.read(this.data);


if (operation.id) {
for (var i=0; i < result.records.length; i++) {
var item = result.records[i];
if (item.data.id === operation.id) {
operation.resultSet = new Ext.data.ResultSet({
records: [item],
total : 1,
loaded : true
});
operation.setSuccessful();
break;
}
}
} else {
Ext.apply(operation, {
resultSet: result
});
operation.setSuccessful();
}

operation.setCompleted();

if (typeof callback == 'function') {
callback.call(scope || this, operation);
}
}
});