Was going through some old stuff and realized I never posted the final code that got me what I needed. Thanks davse04 for the tip on hydrating. Within the original github report listed, here's where I added the hydrate for Project at the task level (in red, near the bottom):
_findCurrentTaskValues: function(rows) {
// snapshots from lookback have the value of fields at the time the
// snap was taken
this.logger.log('_findCurrentTaskValues',rows.length);
var deferred = Ext.create('Deft.Deferred');
this.setLoading('Fetching current task data...');
var me = this;
var project_field = this.getSetting('typeField');
var rows_by_oid = {};
Ext.Array.each(rows, function(row) {
rows_by_oid[row.ObjectID] = row;
});
var task_oids = Ext.Array.pluck(rows,'ObjectID');
this.logger.log("# of tasks to fetch:", task_oids.length);
var filter_array = task_oids;
var chunk_size = 300;
if ( !this.isExternal() ) {
chunk_size = 1000;
}
var array_for_filters = [];
while (filter_array.length > 0) {
array_for_filters.push(filter_array.splice(0, chunk_size));
}
var promises = [];
Ext.Array.each(array_for_filters,function(filters) {
//var filters: Rally.data.wsapi.Filter.or(filters),
var filters = [
{property:'_TypeHierarchy', value:'Task'},
{property:'ObjectID',operator:'in',value:filters},
{property: '__At',value: 'current'}
];
promises.push( function() {
var config = {
filters: filters,
fetch : ['Name',project_field,'WorkProduct','Project'],
/* I added Project here and hydrated it */
hydrate: ['Project'],
useHttpPost: true
};
return me._loadSnapshots(config);
});