Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sails.js model - insert or update records

Been trying out Sails.js and I'm writing an app that imports data from a third-party API and saves in into a MySQL table. Basically I'm trying to sync data over to my app for further analysis, updating my records or creating new records as needed.

I've looked through Sails' API and I see methods to find, create and update records but no built-in method to insert/update records based on the situation. Did I overlook something, or will I need to implement this myself?

If I have to implement this myself, does anyone know of a good design pattern for insert/update?

This is what I think it might look like…

_.each(importedRecords, function(record){
  MyModel.find({id: record.id}).exec(function findCB(err, found){
    if(found.length){
      MyModel.update(record.id, task).exec(function(err, updated){
        if(err) { //returns if an error has occured, ie id doesn't exist.
          console.log(err);
        } else {
          console.log('Updated MyModel record '+updated[0].name);
        }
      });
    }else{
       MyModel.create(record).exec(function(err, created){
         if(err) { //returns if an error has occured, ie invoice_id doesn't exist.
           console.log(err);
         } else {
           console.log('Created client record '+created.name);
         }
       });
     }
   });
 });

Am I headed in the right direction, or is there a more elegant solution?

Also, I'm dealing with a lot of different models in this app, which would mean recreating this block of code across each of my models. Is there a way I can extend the base Model object to add this functionality for all models.

Thanks, John

like image 928
Critical Mash Avatar asked Sep 19 '14 15:09

Critical Mash


1 Answers

I have rewritten Critical Mash code, so its way less code, and more generic. Now you can call updateOrCreate the same way you call findOrCreate. And it looks like that:

module.exports.models = {
    updateOrCreate: function(criteria, values){
        var self = this; // reference for use by callbacks
        // If no values were specified, use criteria
        if (!values) values = criteria.where ? criteria.where : criteria;

        return this.findOne(criteria).then(function (result){
          if(result){
            return self.update(criteria, values);
          }else{
            return self.create(values);
          }
        });
    }
};

So that way you can write criteria the same way. no need to work on the key, and the code is so much simpler.

like image 111
Stas Arshanski Avatar answered Oct 19 '22 09:10

Stas Arshanski