The games cache

When we delete a game, we need to update the gameIds cache of the two teams it involved.

Remember our teams keep an array of each game they are in

You may first try to do it like this:

client/views/game.js

...
  "click a.delete-game": function(e, tpl){
    e.preventDefault();
    var gameId  = this._id;
    var teamIdA = this.teams[0]._id;
    var teamIdB = this.teams[1]._id;

    Games.remove(gameId, function (error) {
      if (!error) {
        Teams.update({_id: [teamIdA, teamIdB]}, {$pull: {gameIds: gameId}});
      }
    });
  },
...

But I receieved a console error:

Exception in delivering result of invoking '/games/remove':
Error: Not permitted. Untrusted code may only update documents by ID. [403]

I did a bit of research and from the Meteor blog itself:

Changes to allow/deny rules

Starting in 0.5.8, client-only code such as event handlers may only update or remove a single document at a time, specified by _id. Method code can still use arbitrary Mongo selectors to manipulate any number of documents at once. To run complex updates from an event handler, just define a method with Meteor.methods and call it from the event handler.

This change significantly simplifies the allow/deny API, encourages better application structure, avoids a potential DoS attack in which an attacker could force the server to do a lot of work to determine if an operation is authorized, and fixes the security issue reported by @jan-glx.

To update your code, change your allow and deny handlers to take a single document rather than an array of documents. This should significantly simplify your code. Also check to see if you have any update or remove calls in your event handlers that use Mongo selectors (this is quite rare), and if so, move them into methods. For details, see the update and remove docs.

Basically they are telling us to only modify documents one by one and only by using a document's _id attribute (I was trying to update multiple teams at once, hence the error). The blog recommends fixing by creating a "method", which basically is a function defined on the server and called from the client. Since we will learn about methods further in the course we'll stick to a client-side solution for now:

client/views/game.js

  ...
  "click a.delete-game": function(e, tpl){
    e.preventDefault();
    var gameId  = this._id;
    var teamIdA = this.teams[0]._id;
    var teamIdB = this.teams[1]._id;

    Games.remove(gameId, function (error) {
      if (!error) {
        Teams.update({_id: teamIdA}, {$pull: {gameIds: gameId}});
        Teams.update({_id: teamIdB}, {$pull: {gameIds: gameId}});
      }
    });
  },
...