Thursday, August 9, 2012

CFQueryReader updated, and missing DB column mappings!

So I use CFQueryReader from Steve Cutter and he has recently updated his reader to support the latest and greatest from ExtJS (4.1 to be specific) which is fantastic because we were hacking the crap out of his previous version to get it working how we needed it to be. Updates include tying directly into the model creation process, which means all you have to do is build the fields and you are set.

So I plopped it in there and it sorta worked. Sorta? Yea, some fields were showing up but others weren't at all. Very confusing. After much testing/debugging (this is the first time I dug through his updated reader so it took a little bit to figure out what was going on) it turns out that if you use the mapping feature to map database columns to your model columns, they get overwritten by the Array reader and turn into numbers vs your DB column names. Minor details right? Well not really. There are some plugins out there that depend on that being there. Bryntum's Scheduler does this (not their fault that the reader did something odd) but I found a workaround so it's not the end of the world. It's really only 3 lines of code that you have to add (but then you have to update your models to reflect the change. I'll get to this in a second.) 

//Around line 189 add this:
nameProperty: null,

//Around line 228
if(pos >= 0){
  fields[i].mapping = pos; //This was a long string but he already assigned it to pos so I'm using it here
} else if (this.nameProperty && fields[i][this.nameProperty]) {
  fields[i].mapping = Ext.Array.indexOf(obj.COLUMNS, fields[i][this.nameProperty].toUpperCase());
}
The nameProperty is right there with the ExtJS Writer object (default is 'mapping' which just so happens to be overwritten!). In the writer it is used to take custom mappings and tie them back so your database doesn't have to remember the frontend model names. So once you add that code to the appropriate places what do you have to do to your models? Well, get rid of the mapping property and instead use ANYTHING else. I use nMap myself and it works like a charm. But you have to add your new nameProperty value to your model and in the reader so your model should look something like this: 
Ext.define('Your.Model.Here', {
  extend: 'Ext.data.Model',
  requires: 'Ext.ux.CFQueryReader',
  proxy: {
    //...
    writer: new Ext.data.JsonWriter({ 
      //...
      nameProperty: 'nMap'
    }),
    reader: {
      type: 'cfquery',
      nameProperty: 'nMap'
    }
  }
});
Once you get to that point you should see your column data show up again and when you update your model data those same columns should be properly mapped to your database names! Amazing. I let 'Cutter' know about it but haven't heard back so we'll see if it's something I did wrong or if it's an actual bug.

No comments:

Post a Comment