Zephaniah Grunschlag
Zephaniah Grunschlag

Reputation: 1083

SailsJS Triggers Update when Creating Object with Associations

I am using Sails v0.10.5.

I have created three models with associations in between them. There is a Candidate model, an Evaluator model and a Rating model by which an evaluator rates a candidate. I am using Waterline associations to automatically keep track of the foreign keys from Rating to Evaluator and Candidate.

I am also using Blueprint to automagically take care of all the CRUD routing for these models.

Unfortunately, whenever I create a new candidate via Blueprint with a url such as http://localhost:1337/rating/create?rating=4&comment=Great&evaluator=3&candidate=2 in addition to triggering the expected CREATE, sails is also going back and calling 2 UPDATE's during which the foreign keys to each of Candidate and Evaluator are being set.

This is causing problem on the front-end of my application as it receives an UPDATE event instead of a CREATE event, and doesn't have the necessary context to properly deal with the new data coming from the server.

Any suggestions for a way around this issue would be helpful!

Here are the Waterline models:

/api/models/Candidate.js:

module.exports = {
  schema: true,
  attributes: {
    name: {
      type: 'string',
      required: true
    },
    status: {
      type: 'string',
      required: true
    },
    role: {
      type: 'string',
      required: true
    },
    ratings: {
      collection: 'rating',
      via: 'candidate'
    }
  }
};

/api/models/Evaluator.js:

module.exports = {
  schema: true,
  attributes: {
    name: {
      type: 'string',
      required: true
    },
    title: {
      type: 'string',
      required: true
    },
    role: {
      type: 'string',
      required: true
    },
    ratings: {
      collection: 'rating',
      via: 'evaluator'
    }
  }
};

/api/models/Rating.js:

module.exports = {
  schema: true,
  attributes: {
    rating: {
      type: 'integer',
      required: true
    },
    comment: {
      type: 'string',
      required: false
    },
    evaluator: {
      model: 'evaluator',
      required: true
    },
    candidate: {
      model: 'candidate',
      required: true
    }
  }
};

Upvotes: 1

Views: 581

Answers (2)

sgress454
sgress454

Reputation: 24958

You can override publishCreate for the Rating model. Most of the code in the default publishCreate method is devoted to figuring out which associations to notify about the new model, and how to notify them; since this is precisely what you don't want, your method in models/Rating.js can be very simple:

publishCreate: function (values, req) {

  // Get all of the "watchers" of the Rating model
  var watchers = Rating.watchers();

  // Remove the socket responsible for the creation, if you don't want
  // it to get the "create" message too
  watchers = _.without(watchers, req.socket);

  // Send a message to the sockets with the "rating" event and the payload
  // expected for the "publishCreate" message
  sails.socket.emit(sockets, "rating", {
      verb: 'created',
      data: values,
      id: values[this.primaryKey]
  });

  // Subscribe all watchers to the new instance, if you're into that
  this.introduce(values[this.primaryKey]);

}

Note that publishCreate is a class method of the model, so it goes outside the attributes object.

Upvotes: 0

Alex J
Alex J

Reputation: 1019

I had a problem similar to this. You can create a filter in your update event to check and see if certain variables were updated, and if they were, call some function that affects your front end.

Upvotes: 1

Related Questions