PDA

View Full Version : [FIXED] Can't have more than 1 hasMany association



stormin_walker
10 Nov 2010, 6:05 PM
I'm guessing I can have more than 1 hasMany association, but it's not working. I can connect one of the associations (always just the first one defined in the "hasMany" array), but never both.

It's easy to recreate. If I add the following to the nestedLoading.js example (in KitchenSink) it breaks:



Ext.regModel('User', {
fields: ['id', 'name'],

hasMany: [{model: 'Order', name: 'orders'},{model: 'Phone', name: 'phones'}],

proxy: {
type: 'ajax',
url : 'src/demos/data/userData.json'
}
});

Ext.regModel('Phone', {
fields: ['id', 'number']
});

Ext.regModel('Order', {
fields: ['id', 'status'],

hasMany: {model: 'OrderItem', name: 'orderItems'}
});

Ext.regModel('OrderItem', {
fields: ['id', 'quantity', 'price', 'name']
});


Now just add some phones to the userData.json:



...
{
"id": 1,
"name": "Ed Spencer",
"phones": [{
"id": 1,
"number": "123456789"
}],
"orders": [
...


Note: when doing this it's just the record for "Ed Spencer" that's broken. So it appears that it's having trouble building the child stores from the JSON.

(BTW: the Sencha forum has become Japanese - my settings are US English but for some reason everything is Japanese all of a sudden - thankfully Chrome translates the pages for me :))

hq242
16 Nov 2010, 9:36 AM
Hi there,

I've noticed the same issue. Defining 2 "hasMany" associations in the same model will just get one child store but never both child stores for both "hasMany" associations.

omarc
17 Nov 2010, 9:09 AM
This might have something to do with it, try changing the readAssociated function in Ext.data.Reader as indicated here:


readAssociated: function(record, data) {
var associations = record.associations.items,
length = associations.length,
association, associationName, associationData, proxy, reader, store, i;

for (i = 0; i < length; i++) {
association = associations[i];
associationName = association.name;
associationData = data[association.associationKey || associationName];

if (associationData) {
//ADD THESE 2 LINES HERE
reader = null;
proxy = null;

proxy = association.associatedModel.getProxy();

// if the associated model has a Reader already, use that
if (proxy) {
reader = proxy.getReader();
}

See if after doing this change you still have the same problem with more than one hasMany.

I found this to be a quick fix for having two associations, one a hasMany and the other a belongsTo.

Let me know if that works for you.

Omar

edspencer
21 Nov 2010, 5:07 PM
I've fixed this in Reader.js now and added unit tests to confirm. This will work correctly in the next release. Thanks for you patience while we sorted this out.

ShiroiSame
26 Nov 2010, 3:31 AM
Ok but... when the next release?!

Because I need to fix this now...

@omarc: your solution works... great!!!

edspencer
26 Nov 2010, 6:17 PM
Should be Monday 28th. This override should get you by until then - just include it after Sencha Touch but before your application:



Ext.override(Ext.data.Reader, {
readAssociated: function(record, data) {
var associations = record.associations.items,
length = associations.length,
association, associationName, associatedModel, associationData, inverseAssociation, proxy, reader, store, i;

for (i = 0; i < length; i++) {
association = associations[i];
associationName = association.name;
associationData = this.getAssociatedDataRoot(data, association.associationKey || associationName);
associatedModel = association.associatedModel;

if (associationData) {
proxy = associatedModel.proxy;

// if the associated model has a Reader already, use that, otherwise attempt to create a sensible one
if (proxy) {
reader = proxy.getReader();
} else {
reader = new this.constructor({
model: association.associatedName
});
}

if (association.type == 'hasMany') {
store = record[associationName]();

store.add.apply(store, reader.read(associationData).records);

//now that we've added the related records to the hasMany association, set the inverse belongsTo
//association on each of them if it exists
inverseAssociation = associatedModel.prototype.associations.findBy(function(assoc) {
return assoc.type == 'belongsTo' && assoc.associatedName == record.constructor.modelName;
});

//if the inverse association was found, set it now on each record we've just created
if (inverseAssociation) {
store.data.each(function(associatedRecord) {
associatedRecord[inverseAssociation.instanceName] = record;
});
}

} else if (association.type == 'belongsTo') {
record[association.instanceName] = reader.read([associationData]).records[0];
}
}
}
}
});

Jeff Blake
24 Jan 2011, 3:35 PM
What's the story with this bug? The above solution did not work.

The weird thing with my case is that if I change the order of the includes for models in the index.html file - it either produces a "property x is undefined"
If I switch the order of the hasMany models, I get no error but instead no data is able to display from the second model.

This is a weird issue, any ideas?

Jeff Blake
24 Jan 2011, 11:19 PM
Here is some more information regarding the bug with hasMany:

Models:


Ext.regModel("Store", {
fields: [
{name: "id", type: "int"},
{name: "name", type: "string"},
{name: "email", type: "string"},
{name: "phone", type: "string"},
{name: "hashed_password", type: "string"}
],

validations: [
{type: 'presence', field: 'hashed_password'},
{type: 'presence', field: 'name'},
{type: 'length', field: 'hashed_password', min: 4},
{type: 'format', field: 'email', matcher: /^[^@][\w.-]+@[\w.-]+[.][a-z]{2,4}$/i}
],
associations: [
{type: 'hasMany', model: 'Deal', name: 'deals'},
{type: 'hasMany', model: 'Earn', name: 'earns'},
{type: 'hasMany', model: 'Reward', name: 'rewards'}
],



});
/**
* @class Deal
* @extends Ext.data.Model
*/
Ext.regModel("Deal", {
fields: [
{name: "id", type: "int"},
{name: "name", type: "string"},
{name: "store_id", type: "integer"},
{name: "description", type: "string"},
{name: "thumbs_up", type: "integer"},
{name: "thumbs_down", type: "integer"}
],

validations: [
// {type: 'presence', field: 'hashed_password'}
],
belongsTo: 'Store'

});


I ommited the other two for brevity

Requested JSON Data:

{
"stores": [
{
"name": "Jeffs store",
"created_at": "2010-12-28T10:04:08Z",
"updated_at": "2011-01-19T00:39:44Z",
"hashed_password": "67ea66ac0f272be8aac494de523892bf0bb646b7",
"id": 1,
"network": "ubc",
"area": null,
"rewards": [
{
"name": "Reward 1",
"created_at": "2011-01-21T08:56:39Z",
"updated_at": "2011-01-21T08:56:39Z",
"store_id": 1,
"id": 1,
"points_required": 1
},
{
"name": "Reward 2",
"created_at": "2011-01-24T22:02:45Z",
"updated_at": "2011-01-24T22:02:45Z",
"store_id": 1,
"id": 2,
"points_required": 2
}
],
"phone": "23123",
"registered_at": "2010-12-28T10:03:00Z",
"deals": [
{
"name": null,
"created_at": "2010-12-29T04:25:13Z",
"updated_at": "2011-01-21T08:28:04Z",
"store_id": 1,
"id": 1,
"active_date": null,
"thumbs_down": null,
"description": null,
"thumbs_up": null,
"created": null
},
{
"name": "My deal",
"created_at": "2010-12-29T04:28:06Z",
"updated_at": "2010-12-29T04:28:06Z",
"store_id": 1,
"id": 2,
"active_date": "2010-12-29T04:27:00Z",
"thumbs_down": null,
"description": "dealie",
"thumbs_up": null,
"created": null
},
{
"name": "HEfd",
"created_at": "2010-12-29T04:33:29Z",
"updated_at": "2010-12-29T04:33:29Z",
"store_id": 1,
"id": 3,
"active_date": "2010-12-29T04:33:00Z",
"thumbs_down": null,
"description": "sdsdd",
"thumbs_up": null,
"created": null
},
{
"name": "Ssdsd",
"created_at": "2011-01-09T07:34:55Z",
"updated_at": "2011-01-09T07:34:55Z",
"store_id": 1,
"id": 4,
"active_date": "2011-01-09T07:34:00Z",
"thumbs_down": null,
"description": "dasdasdasdasd",
"thumbs_up": null,
"created": null
},
{
"name": null,
"created_at": "2011-01-14T00:57:30Z",
"updated_at": "2011-01-14T00:57:30Z",
"store_id": 1,
"id": 6,
"active_date": null,
"thumbs_down": null,
"description": null,
"thumbs_up": null,
"created": null
}
],
"earns": [
{
"name": "JEFF",
"created_at": "2011-01-25T06:18:11Z",
"updated_at": "2011-01-25T06:20:24Z",
"store_id": 1,
"id": 1
}
],
"email": "123@gmail.com"
}
]
}

I get errors while using TPL to render the data. the WEIRDEST thing about it is that I can get one of the three hasMany to display it's data (which tells me they are configured properly, but cannot get the other 2 to show up.)

And the WEIRDEST thing of all is that if I change up the ordering of my models in the index.html file I can predictably cause errors for the Deals model if it's not included first.

My Xtemplate:


itemTpl: new Ext.XTemplate(
'<tpl for=".">',
'<h1>{name}{records}</h1>',
'<h2>{network}</h2>',
'<h2>{phone}</h2>',
'<h2>{email}</h2>',
'</tpl>',
'<tpl for="earns">',
'<h1>{name}{records}</h1>',
'<h2>{description}</h2>',
'</tpl>',
'<tpl for="deals">',
'<h1>{name}{records}</h1>',
'<h2>{description}</h2>',
'</tpl>',
'<tpl for="rewards">',
'<h1>{name}{records}</h1>',
'<h2>{description}</h2>',
'</tpl>',

gp40
25 Jan 2011, 1:01 PM
I'm having the same issue and the work around does not seem to help. Looking forward to a solution/workaroud. Thx. /Greg

emilschutte
31 Jan 2011, 11:23 PM
edspencer's patch worked for me, but note you also need another method on Ext.data.Reader:



getAssociatedDataRoot: function(data, associationName) {
return data[associationName];
}


I'm using 1.0.

beetree
21 Aug 2011, 11:04 AM
(BTW: the Sencha forum has become Japanese - my settings are US English but for some reason everything is Japanese all of a sudden - thankfully Chrome translates the pages for me :))

Haha, I have the same issue now. I remember seeing you post this before. How did you solve it? Seems like we not only have to fix buggs in the lib but also on the forum :)

edspencer
29 Aug 2011, 12:33 PM
@beetree what version are you on?

bk.dbe
1 Sep 2011, 1:32 AM
Hello all,

I had the XTemplate + Models associations problem, with Sencha Touch 1.1.0.
I followed the solution provided in this topic : http://www.sencha.com/forum/showthread.php?115541-belongsTo-association-and-XTemplate

I hope the next version will be fix :) (I don't like to use custom patches in production environment).

Thanks.

beetree
1 Sep 2011, 6:09 AM
@beetree what version are you on?

Oh, this is not a Sencha touch issue. This is an issue with the forum on this website. It has only happened to me once and I think I was using Firefox 6 when it happened.

edspencer
1 Sep 2011, 2:34 PM
Ok, this is in the tracker for 2.0.0 so we'll make sure this functions correctly there. 2.0 is not far away and as the team's attention is focused there now I think we'll get you the full functionality faster that way

beetree
1 Sep 2011, 4:09 PM
Ok, this is in the tracker for 2.0.0 so we'll make sure this functions correctly there. 2.0 is not far away and as the team's attention is focused there now I think we'll get you the full functionality faster that way

Awesome! Can you give any hints on what will be in 2.0.0? Is there an official list?

edspencer
1 Sep 2011, 4:13 PM
It's all about performance, stability, and bringing into par with Ext JS 4's advancements in class system and MVC. I think you're going to love it, and you don't have long to wait :)

beetree
5 Sep 2011, 8:52 AM
I think you're going to love it, and you don't have long to wait :)

Great!

Möhre
25 Oct 2011, 5:21 AM
Not fixed in 1.1.1?!

Has this been fixed in 2.0.0 dev preview?

TommyMaintz
19 Jan 2012, 2:05 PM
This has been fixed and will be part of the next Touch 2.0 release. Thanks for the detailed reports!

MonkeySleeve
18 Dec 2013, 7:27 AM
If this has been fixed i can't seem to find what i'm doing wrong then. Can someone help me?http://www.sencha.com/forum/showthread.php?278742-Load-multiple-hasMany-not-possible&p=1018930#post1018930