diff --git a/src/controllers/user.js b/src/controllers/user.js index 1d7414695a..986b5d36da 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -40,7 +40,6 @@ api.marketBuy = function(req, res, next){ }) } - /* ------------------------------------------------------------------------ Tasks @@ -65,12 +64,15 @@ api.verifyTaskExists = function(req, res, next) { }; function deleteTask(user, task) { - user[task.type+'s'].id(task.id).remove(); + var i = _.findIndex(user[task.type+'s'], {id:task.id}); + if (~i) { + user[task.type+'s'].splice(i, 1) + //user.markModified(task.type+'s') + } }; function addTask(user, task) { task = helpers.taskDefaults(task); - task._id = task.id; user[task.type+'s'].unshift(task); return task; } diff --git a/src/models/challenge.js b/src/models/challenge.js index 6ad5725168..497c9093dd 100644 --- a/src/models/challenge.js +++ b/src/models/challenge.js @@ -2,7 +2,6 @@ var mongoose = require("mongoose"); var Schema = mongoose.Schema; var helpers = require('habitrpg-shared/script/helpers'); var _ = require('lodash'); -var TaskSchema = require('./task').schema; var Group = require('./group').model; var ChallengeSchema = new Schema({ @@ -10,10 +9,10 @@ var ChallengeSchema = new Schema({ name: String, shortName: String, description: String, - habits: [TaskSchema], - dailys: [TaskSchema], - todos: [TaskSchema], - rewards: [TaskSchema], + habits: [Schema.Types.Mixed], + dailys: [Schema.Types.Mixed], + todos: [Schema.Types.Mixed], + rewards: [Schema.Types.Mixed], leader: {type: String, ref: 'User'}, group: {type: String, ref: 'Group'}, timestamp: {type: Date, 'default': Date.now}, @@ -31,6 +30,11 @@ ChallengeSchema.virtual('tasks').get(function () { // FIXME this isn't always triggered, since we sometimes use update() or findByIdAndUpdate() // @see https://github.com/LearnBoost/mongoose/issues/964 ChallengeSchema.pre('save', function(next){ + // @see comment in user.js pre(save) + this.markModified('habits'); + this.markModified('dailys'); + this.markModified('todos'); + this.markModified('rewards'); this.memberCount = _.size(this.members); next() }) @@ -39,11 +43,11 @@ ChallengeSchema.methods.toJSON = function(){ var doc = this.toObject(); doc.memberCount = doc.members ? _.size(doc.members) : doc.memberCount; // @see pre('save') comment above doc._isMember = this._isMember; - _.each(['habits','dailys','todos','rewards'], function(type){ - _.each(doc[type],function(task){ - task.id = task._id; - }) - }) +// _.each(['habits','dailys','todos','rewards'], function(type){ +// _.each(doc[type],function(task){ +// task.id = task._id || task.id; +// }) +// }) return doc; } diff --git a/src/models/user.js b/src/models/user.js index 48ff54f540..df2396e6b3 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -8,7 +8,6 @@ var mongoose = require("mongoose"); var Schema = mongoose.Schema; var helpers = require('habitrpg-shared/script/helpers'); var _ = require('lodash'); -var TaskSchema = require('./task').schema; // User Schema // ----------- @@ -191,10 +190,10 @@ var UserSchema = new Schema({ challenges: [{type: 'String', ref:'Challenge'}], - habits: [TaskSchema], - dailys: [TaskSchema], - todos: [TaskSchema], - rewards: [TaskSchema], + habits: [Schema.Types.Mixed], + dailys: [Schema.Types.Mixed], + todos: [Schema.Types.Mixed], + rewards: [Schema.Types.Mixed], }, { strict: true, @@ -209,12 +208,11 @@ UserSchema.methods.toJSON = function() { doc.filters = {}; doc._tmp = this._tmp; // be sure to send down drop notifs - // TODO why isnt' this happening automatically given the TaskSchema.methods.toJSON above? - _.each(['habits','dailys','todos','rewards'], function(type){ - _.each(doc[type],function(task){ - task.id = task._id; - }) - }) +// _.each(['habits','dailys','todos','rewards'], function(type){ +// _.each(doc[type],function(task){ +// task.id = task._id || task.id; +// }) +// }) return doc; }; @@ -229,7 +227,16 @@ UserSchema.virtual('tasks').get(function () { // Custom setter/getter virtuals? UserSchema.pre('save', function(next) { - //this.markModified('tasks'); + // I finally figured out when markModified() is required - when using Schema.Type.Mixed or Array. Let's say you + // have `tasks: [{text:String, notes:String}]`. Because it's a defined schema, Mongoose can track attribute changes. + // But if you have `tasks: [Schema.Types.Mixed]`, Mongoose can't track underlying attr changes - only top-level changes + // (via splice(), push/unshift(), etc). Adding a workaround here, which is very inefficient - we'll want to find + // each location where a task attr is modified and use `user.markModified(task.type+'s')` + // (@see https://github.com/HabitRPG/habitrpg/issues/1711#issuecomment-27626467) + this.markModified('habits'); + this.markModified('dailys'); + this.markModified('todos'); + this.markModified('rewards'); if (!this.profile.name) { var fb = this.auth.facebook;