PDA

View Full Version : hasOne association and the empty model



rob.pridham
16 Dec 2013, 4:59 AM
I have a conceptual model where Users can be related to Projects by the existence of a UserPermission object that links the two. (It's done this way rather than simple ownership, because the UserPermission object describes granular stuff like read/write access etc)

In ExtJS, I determined that to be represented by:


User hasMany UserPermission
UserPermission hasOne User
UserPermission hasOne Project

Here's my model for the UserPermission, with some stuff cut out.


Ext.define('MyApp.model.UserPermissionsModel', {
extend: 'Ext.data.Model',

requires: [
'MyApp.model.ProjectsModel'
],
uses: [
'MyApp.model.UserModel',
'MyApp.model.ProjectsModel'
],

fields: [
...
{
name: 'projectID'
},
...
],

hasOne: [
{
associationKey: 'projectID',
model: 'MyApp.model.ProjectsModel',
primaryKey: 'databaseID',
foreignKey: 'projectID',
getterName: 'getProject',
setterName: 'setProject'
}
],

proxy: {
type: 'ajax',
url: '/permissionslist',
reader: {
type: 'json',
root: 'permissionList'
}
}In one of my UIs, I want to show permissions entries for a particular user. I call this:


var grid = this.query('*[itemId^=projectsGrid]')[0];
grid.bindStore(user.permissions());
user.permissions().load();This works fine. We now have JSON data loaded from the server, filtered such that it only represents the user in question. Great.

However I now want to reference the UserPermission's associated Project, linked by the hasOne relationship above.

For that we need to see the Project model, which is this:


Ext.define('MyApp.model.ProjectsModel', {
extend: 'Ext.data.Model',

fields: [
{
name: 'databaseID'
},
{
name: 'name'
}
],

proxy: {
type: 'ajax',
url: '/projectslist',
reader: {
type: 'json',
root: 'projects'
}
}
});and with that in place, for a particular UserPermission record, I attempt to get the Project:


console.log("Permission record "+record+" clicked");
var pg = record.getProject( function(loadedRecord)
{
console.log("Project loaded: "+loadedRecord);
} );This returns a model object of the correct type. However, the data is unpopulated, and no AJAX request is ever made to /projectslist.

When I step into the getter, I see this:


if (options.reload === true || model[instanceName] === undefined) {Now options.reload is undefined, instance name is 'MyApp.model.ProjectsModelHasOneInstance', and the model it references is defined. Therefore the condition is false, and the code inside that would apparently load the model's data is not called.

What am I doing wrong? My suspicion is way back at the store creation, but I'm a bit lost. Thanks for reading.

rob.pridham
16 Dec 2013, 7:34 AM
OK, so another whole day of faffing about with this, and by chance looking at this blog (http://extjs-tutorials.blogspot.co.uk/2012/05/extjs-belongsto-association-rules.html) again, I discover that if I remove associationKey from my hasOne relationship, keeping foreignKey, the data now gets loaded on demand when I call my getter.

The reverse does not apply, i.e. just associationKey does not make for automatic loading.

This behaviour doesn't seem to be documented anywhere.

However this is still not what I want, because I want to show the data in a renderer, which is synchronous and thus requires having prior knowledge of the value.

Lazy loading is a pain here, and it shouldn't be rocket science to have the relationships fulfilled properly upon populating the top level object. Anyone?

Kevin Jackson
24 Dec 2013, 10:03 AM
When the store loads, you can return the records and their associations and the associated data will then be there.
You could just set autoLoad to true and then all data would be there and you would have access to it.