3

Expected Behavior:

After successfully updating a record using .update(), the record's updated_at field should auto-update to the current time.

Note: I changed the autoUpdatedAt setting (also mentioned here) using autoUpdatedAt: 'updated_at' in config.models so the field is titled updated_at instead of updatedAt. It should still have the same functionality I would assume.

Actual Behavior:

The model successfully updates, but it does not update the updated_at field.

Code Run:

model.update(primary, data)
.then(function updateCB(updated){
  // error handling
  sails.log('Updated successfully');
  sails.log(updated);
});

Questions:

  • Why is this?
  • How do I fix this?

Result: Issue for Sails

I was able to reproduce it on a new project, so it looks like it's a problem with sails. Issue link: https://github.com/balderdashy/sails/issues/3821

See my answer below for more info.

Community
  • 1
  • 1
smileham
  • 1,430
  • 2
  • 16
  • 28

2 Answers2

5

I can't answer the 'why' I tried the same thing and ran into the same issue. As for how to fix it -

I made it an attribute in my model file for any models I wanted it on and filled it out like so:

    updated_at:{
        type: 'datetime',
        defaultsTo: function(){return new Date();}
    }

With the column in my DB (mysql in this case) being set to NOT NULL and DATETIME and set to update CURRENT_TIMESTAMP on UPDATE.

You can also put this in code if you don't have access to your db, just before your update call:

data.updated_at = new Date();
model.update(primary,data)....

That will accomplish the same thing.

This has been the simplest work around I've been able to come up with.

I got thinking about this and I came up with a third option, a model method written like so:

attributes:{
    //stuffs
},
beforeUpdate: function(obj, next){
    obj.updated_at = new Date();
    return next(null, obj);
}

The null in the first position is because as far as I can tell Sails expects an error object throughout the call chain so if I passed nothing along then the whole thing crapped out.

Ryan
  • 5,644
  • 3
  • 38
  • 66
  • Are you sure that works for updating? It'll set default on create, so that'd work for `created_at`, but I'm not sure about updating. Obviously I'd prefer a config solution, but until Sails fixes it, I'm open to a manual solution. – smileham Aug 25 '16 at 21:44
  • @smileham, oh opps, I forgot a step, there are 2 ways to handle this. Since I have full control over my project I did it at the db level but you can do it in code as well see my edit. – Ryan Aug 25 '16 at 21:59
  • Gotcha. When updating though, does `updated_at` change values? It already has a value from when it was created. – smileham Aug 25 '16 at 22:02
  • From the sails docs: defaultsTo - When a record is created, if no value was supplied, the record will be created with the specified defaultsTo value. The supplied value can also be a function that waterline will run while creating the record. – smileham Aug 25 '16 at 22:02
  • Got it! The edit makes sense, and thank you for that. Yes, before every time I call `.update()` I can manually set `updated_at`, but that takes away the advantage of an auto update in the first place since it's essentially a static attribute now (and I'd rather not go through all my code to change that). Still two good solutions though - I appreciate it. I'll try the DB route for now. – smileham Aug 25 '16 at 22:07
  • @smileham, that's why I went with the DB route as well – Ryan Aug 25 '16 at 22:12
  • Thanks for that :) I always appreciate multiple solutions to a problem, so you definitely helped me! – smileham Aug 25 '16 at 22:27
0

Result: Issue for Sails

I was able to reproduce it on a new project, so it looks like it's a problem with sails. Issue link: https://github.com/balderdashy/sails/issues/3821

Code Run:

Test.create()
.then(function(created){
    sails.log('created');
    sails.log(created);

    Test.update(created, {})
    .then(function(updated){
        sails.log('updated');
        sails.log(updated[0]);

        Test.findOne(updated)
        .then(function(found){
            sails.log('found');
            sails.log(found);

            res.end();
        });
    });
});

Code Result:

debug: created
debug: { createdAt: '2016-08-25T21:35:46.679Z',
  updated_at: '2016-08-25T21:35:46.679Z',
  id: 1 }
debug: updated
debug: { createdAt: '2016-08-25T21:35:46.679Z',
  updated_at: '2016-08-25T21:35:46.679Z',
  id: 1,
  updatedAt: '2016-08-25T21:35:46.698Z' }
debug: found
debug: { createdAt: '2016-08-25T21:35:46.679Z',
  updated_at: '2016-08-25T21:35:46.679Z',
  id: 1,
  updatedAt: '2016-08-25T21:35:46.698Z' }

Looks like Sails is still adding an updatedAt field which isn't saving to my SQL database.

smileham
  • 1,430
  • 2
  • 16
  • 28