mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
Properly fix duplicate course instances
* Add script to merge existing course instances * Have client only send one course instance creation * Have server return existing course instance if one for the given classroom/course exists * Remove bandaid code from ClassroomView
This commit is contained in:
parent
3acb2a4c7a
commit
bb38c58903
4 changed files with 83 additions and 7 deletions
|
@ -53,11 +53,6 @@ module.exports = class ClassroomView extends RootView
|
|||
@sessions = new CocoCollection([], { model: LevelSession })
|
||||
|
||||
onCourseInstancesSync: ->
|
||||
# clear duplicates with lodash magic
|
||||
groups = _.groupBy @courseInstances.models, (ci) -> ci.get('courseID')
|
||||
@courseInstances.reset(_.map(_.values(groups), _.first))
|
||||
# TODO: Make having multiple course instances for a classroom/course pair impossible in the db
|
||||
|
||||
@sessions = new CocoCollection([], { model: LevelSession })
|
||||
for courseInstance in @courseInstances.models
|
||||
sessions = new CocoCollection([], { url: "/db/course_instance/#{courseInstance.id}/level_sessions", model: LevelSession })
|
||||
|
@ -205,7 +200,9 @@ module.exports = class ClassroomView extends RootView
|
|||
|
||||
if courseInstance.isNew()
|
||||
# adding the first student to this course, so generate the course instance for it
|
||||
courseInstance.save(null, {validate: false})
|
||||
if not courseInstance.saving
|
||||
courseInstance.save(null, {validate: false})
|
||||
courseInstance.saving = true
|
||||
courseInstance.once 'sync', onCourseInstanceCreated
|
||||
else
|
||||
onCourseInstanceCreated()
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
var currentClassroom = null;
|
||||
var courseInstances = {};
|
||||
var count = 0;
|
||||
load('node_modules/lodash/lodash.js');
|
||||
|
||||
function toStrings(array) {
|
||||
return _.sortBy(_.map(array, function(item) { return item.valueOf(); }));
|
||||
}
|
||||
|
||||
function mergeMembers(members1, members2) {
|
||||
var members1 = members1 || [];
|
||||
var members2 = members2 || [];
|
||||
var members = members1.concat(members2);
|
||||
if(!members.length)
|
||||
return [];
|
||||
print('concat:');
|
||||
print('\t', members1.length, JSON.stringify(toStrings(members1)));
|
||||
print('\t', members2.length, JSON.stringify(toStrings(members2)));
|
||||
print('\t', members.length, JSON.stringify(toStrings(members)));
|
||||
members = _.uniq(members, false, function(member) { return member.valueOf() });
|
||||
print('\t', members.length, JSON.stringify(toStrings(members)));
|
||||
return members;
|
||||
}
|
||||
|
||||
var count = 0;
|
||||
|
||||
db.course.instances.find({classroomID: {$exists: true}}).sort({classroomID: 1}).forEach(function(courseInstance) {
|
||||
count += 1;
|
||||
if(count % 100 === 0) { print('count', count); }
|
||||
if (!currentClassroom || !courseInstance.classroomID.equals(currentClassroom)) {
|
||||
currentClassroom = courseInstance.classroomID;
|
||||
courseInstances = {};
|
||||
}
|
||||
if (courseInstances[courseInstance.courseID]) {
|
||||
var keeper = courseInstances[courseInstance.courseID];
|
||||
if (!keeper.classroomID.equals(courseInstance.classroomID)) {
|
||||
throw new Error('This should not happen.');
|
||||
return;
|
||||
}
|
||||
print('duplicate...', count, 'in classroom', courseInstance.classroomID, keeper.members.length, courseInstance.members.length);
|
||||
print(JSON.stringify(courseInstance, null, '\t'));
|
||||
print(JSON.stringify(keeper, null, '\t'));
|
||||
keeper.members = mergeMembers(keeper.members, courseInstance.members);
|
||||
print('new members', keeper.members.length);
|
||||
print('save', db.course.instances.save(keeper));
|
||||
print('remove', db.course.instances.remove({_id:courseInstance._id}), true);
|
||||
print('keeper id', keeper._id)
|
||||
}
|
||||
else {
|
||||
courseInstances[courseInstance.courseID] = courseInstance;
|
||||
}
|
||||
});
|
|
@ -133,7 +133,14 @@ CourseInstanceHandler = class CourseInstanceHandler extends Handler
|
|||
Course.findById req.body.courseID, (err, course) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
return @sendNotFoundError(res, 'Course not found') unless course
|
||||
super(req, res)
|
||||
q = {
|
||||
courseID: mongoose.Types.ObjectId(req.body.courseID)
|
||||
classroomID: mongoose.Types.ObjectId(req.body.classroomID)
|
||||
}
|
||||
CourseInstance.findOne(q).exec (err, doc) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
return @sendSuccess(res, @formatEntity(req, doc)) if doc
|
||||
super(req, res)
|
||||
|
||||
makeNewInstance: (req) ->
|
||||
doc = new CourseInstance({
|
||||
|
|
|
@ -23,6 +23,25 @@ describe 'POST /db/course_instance', ->
|
|||
expect(res.statusCode).toBe(200)
|
||||
expect(body.classroomID).toBeDefined()
|
||||
done()
|
||||
|
||||
it 'returns the same CourseInstance if you POST twice', (done) ->
|
||||
test = @
|
||||
url = getURL('/db/course_instance')
|
||||
data = {
|
||||
name: 'Some Name'
|
||||
courseID: test.course.id
|
||||
classroomID: test.classroom.id
|
||||
}
|
||||
request.post {uri: url, json: data}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.classroomID).toBeDefined()
|
||||
firstID = body._id
|
||||
request.post {uri: url, json: data}, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.classroomID).toBeDefined()
|
||||
secondID = body._id
|
||||
expect(firstID).toBe(secondID)
|
||||
done()
|
||||
|
||||
it 'returns 404 if the Course does not exist', (done) ->
|
||||
test = @
|
||||
|
|
Loading…
Reference in a new issue