سؤال

Why on earth is this update failing? This is basic, I've done this many other times.

Meteor.users.update(id, {$set: {lastname: "Archer"}});

That query above has even been simplified from what it originally was, and it's still having the same problem. Originally I was compiling the update programatically:

console.log(obj);
console.log(id);
if (obj) collection.update(id, obj);

Here is my exact output from those lines:

Object {$set: Object}
    $set: Object
        lastname: "Archer"
        __proto__: Object
        __proto__: Object
main.js?b9104f881abb80f93da518738bf1bfb4cab0b2b6:68

YXeudfnHyKmsGXaEL
main.js?b9104f881abb80f93da518738bf1bfb4cab0b2b6:69

update failed: MongoError: invalid query
debug.js:41

The id is correct, and if the obj has something wrong with it, it'll be news to me!

Now, I'm quite positive this has nothing to do with my allow function. In the first tests of this part of my program, I actually did get the update not allowed (or whatever it is) error, but I modified my allow function to take this into account, and that error went away.

Here's my allow function. I have a user system where a user can have a student object that "mirrors" it's name information, hence the added complexity. That portion of the function is only engaged in certain circumstances, and it doesn't alter the behavior of the allowance.

Meteor.users.allow({
    update: function (userId, doc, fields, modifier) {
        var allow = (userId && (doc._id === userId) && _.without(fields, 
                    'firstname', 'lastname', 'student_ids', 'payment_ids', 'phones').length == 0) || Meteor.user().admin;
        if (allow && modifier.$set && (_.contains(fields, 'firstname') || _.contains(fields, 'lastname'))) {
            var user = Meteor.users.findOne(userId);
            var obj = {};
            if (modifier.$set.firstname) obj.firstname = modifier.$set.firstname;
            if (modifier.$set.lastname) obj.lastname = modifier.$set.lastname;
            if (obj) Students.update({_id: {$in: user.student_ids}, reflectsUser: true}, {$set: obj});
        }
        return allow;
    }
});
هل كانت مفيدة؟

المحلول

It turns out my allow function was the problem, but in a bit of a sneaky way.

The Meteor.users.update call wasn't actually the one that was failing, it was this one:

Students.update({_id: {$in: user.student_ids}, reflectsUser: true}, {$set: obj});

I wasn't properly checking that user.student_ids field, so if it was undefined (that user didn't have any students) then the query was invalid. Throwing in a line to vet that array:

var student_ids = user.student_ids || [];

solved the problem.

Since the Meteor error didn't tell me which query was invalid, it led me on a bit of a wild goose chase. Just goes to show that good errors can go a long way!

Also, performing database queries that have other database queries as side-effects is something to be done very carefully.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top