简体   繁体   中英

How to update record in SailsJS without triggering model lifecycle callbacks

I have model where I need to rebuild records after updating or saving new record to table. The problem is that afterUpdate callback is triggered on fixTree made updates.

module.exports = {
  identity: 'Role',
  attributes: {
    ..
  },
  afterCreate: function(rec, cb) {
    fixTree();
    cb();
  },
  afterUpdate: function(rec, cb) {
    fixTree();
    cb();
  },
}

function fixTree() {
  /* code here */
  Role.update(....); // <--- do not trigger afterUpdate
  /* and code here */
}

You can add a flag to monitor if tree update is in progress:

var fixTreeInProgress = false;

module.exports = {
  identity: 'Role',
  attributes: {
  //..
  },
  afterCreate: function(rec, cb) {
    if (!fixTreeInProgress) {
      fixTree();
    }
    cb();
  },
  afterUpdate: function(rec, cb) {
    if (!fixTreeInProgress) {
      fixTree();
    }
    cb();
  },
}

function fixTree() {
  /* code here */
  fixTreeInProgress = true;
  //passing callback to clear out flag when update is complete
  Role.update(criteria, updatedRecords, function fixTreeUpdateCallback() {
    fixTreeInProgress = false;
  }); // <--- do not trigger afterUpdate

  /* and code here */
}

But keep in mind : if data will be updated in another request while Role.update is in progress, it will make your data inconsistent:

Consider such scenario:

  1. App receives data update request.
  2. Controller updates data, lifecycle callback is called
  3. fixTreeInProgress var is false , so we launch fixTree() , and set fixTreeInProgress to true
  4. App receives one more data update request.
  5. Controller updates data, lifecycle callback is called, fixTreeInProgress var is true , so we don't launch fixTree()
  6. Role.update() is finished, fixTreeInProgress set to false

In this case we'll have tree updated with old version of data.

You need to use some kind of task queue (and, optionally, some kind of debounce function) to handle such situations.

I ended up using controller actions

create: function(req, res) {
    var data = {};
    data.name = req.body.name;
    data.parent = req.body.parent;
    Role.create(data, function(err, record) {
        Role.tree.fix(function() {
            res.ok(record);
        });
    });
},
update: function(req, res) {
    var data = {};
    data.name = req.body.name;
    data.parent = req.body.parent;
    Role.update(req.params.id, data, function(err, record) {
        Role.tree.fix(function() {
            res.ok(record);
        });
    });
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM