diff --git a/app.js b/app.js index 6512680aa..f5714fe6e 100644 --- a/app.js +++ b/app.js @@ -97,7 +97,7 @@ app.use('/api', (err, req, res, next) => { res.status(err.status || 500); res.json({ message: err.message, - error: app.get('env') === 'development' ? err : null + error: app.get('env') === 'development' ? err : {} }); }); @@ -109,7 +109,7 @@ app.use('/', (err, req, res, next) => { res.status(err.status || 500); res.render('error', { message: err.message, - error: app.get('env') === 'development' ? err : null + error: app.get('env') === 'development' ? err : {} }); }); diff --git a/models/action.js b/models/action.js index 43e38795c..8173db9f9 100644 --- a/models/action.js +++ b/models/action.js @@ -42,29 +42,58 @@ ActionSchema.statics.findByItemIdArray = function(item_ids) { * @param {String} ids array of user identifiers (uuid) */ ActionSchema.statics.getActionSummaries = function(item_ids) { - return ActionSchema.statics.findByItemIdArray(item_ids).then((rawActions) => { - // Create an object with a count of each action type for each item - const actionSummaries = rawActions.reduce((actionObj, action) => { - if (!actionObj[`${action.item_id}_${action.action_type}`]) { - actionObj[`${action.item_id}_${action.action_type}`] = { - id: action.id, - item_id: action.item_id, - item_type: action.item_type, - action_type: action.action_type, - count: 1, - current_user: false //Update this later when we have authentication - }; - } else { - actionObj[`${action.item_id}_${action.action_type}`].count ++; + return Action.aggregate([ + { + + // only grab items that match the specified item id's + $match: { + item_id: { + $in: item_ids + } } - return actionObj; - }, {}); - // Return an array extracted from the actionSummaries object - return Object.keys(actionSummaries).reduce((actions, key) => { - actions.push(actionSummaries[key]); - return actions; - }, []); - }); + }, + { + $group: { + + // group unique documents by these properties, we are leveraging the + // fact that each uuid is completly unique. + _id: { + item_id: '$item_id', + action_type: '$action_type' + }, + + // and sum up all actions matching the above grouping criteria + count: { + $sum: 1 + }, + + // we are leveraging the fact that each uuid is completly unique and + // just grabbing the last instance of the item type here. + item_type: { + $last: '$item_type' + } + } + }, + { + $project: { + + // suppress the _id field + _id: false, + + // map the fields from the _id grouping down a level + item_id: '$_id.item_id', + action_type: '$_id.action_type', + + // map the field directly + count: '$count', + item_type: '$item_type', + + // set the current user to false here + current_user: {$literal: false} + } + } + ]) + .exec(); }; /* diff --git a/tests/models/action.js b/tests/models/action.js index 917191690..80a8ae814 100644 --- a/tests/models/action.js +++ b/tests/models/action.js @@ -52,10 +52,9 @@ describe('Action: models', () => { it('should return properly formatted summaries from an array of item_ids', () => { return Action.getActionSummaries(['123', '789']).then((result) => { expect(result).to.have.length(3); + const sorted = result.sort((a, b) => a.count - b.count); - delete sorted[0].id; - delete sorted[1].id; - delete sorted[2].id; + expect(sorted[0]).to.deep.equal({ action_type: 'like', count: 1, @@ -63,6 +62,7 @@ describe('Action: models', () => { item_type: 'comments', current_user: false }); + expect(sorted[1]).to.deep.equal({ action_type: 'like', count: 1, @@ -70,6 +70,7 @@ describe('Action: models', () => { item_type: 'comments', current_user: false }); + expect(sorted[2]).to.deep.equal({ action_type: 'flag', count: 2,