vidigami / backbone-orm

A polystore ORM for Node.js and the browser
http://vidigami.github.io/backbone-orm
MIT License
238 stars 15 forks source link

Good practice for lastModified timestamp / hooks in general? #52

Open thokari opened 9 years ago

thokari commented 9 years ago

Hi again! I wanted to quickly ask, if there is a recommended way to set both 'createdAt' timestamp and 'updatedAt' timestamp. The 'created' one could be defined in the model as having a default value of 'new Date()', but how about the 'updatedAt' one? I was just evaluating waterline, and came across this feature, which I found pretty nice: https://github.com/balderdashy/waterline-docs/blob/master/models.md#autocreatedat

Related question: Are there any hooks, like 'beforeSave' or similar, that could be used for that purpose? Excuse me if that should be covered by Backbone knowledge I do not yet have ;)

Again, thanks for your help, it is very much appreciated! Thomas

jotham commented 8 years ago

Hi, I'm looking for similar insight here. Any advice appreciated.

kmalakoff commented 8 years ago

Currently, there are no special hooks like in Waterline.

You could just override the save method like here: http://stackoverflow.com/questions/16477446/backbone-js-set-callback-on-before-save

Or if you want it across multiple models, you could create your own base model with a modified save method.

If you want to update it across all models, you could override the method that upgrades the model and wrap the save method.

jotham commented 8 years ago

So currently I have this, but it feels a bit brittle (no real schema check or injection) https://gist.github.com/jotham/e579239e21e18eb27c56

Should I consider creating my own base model with the functionality from your stackoverflow link?

Sorry, I'm relatively new to backbone. Only reason I bring this up is this process might be a good lesson for other people in the community starting out with backbone / backbone-orm.

kmalakoff commented 8 years ago

It's pretty good as you have it. Not sure if you need to generalize the hook the the stackoverflow link.

You should be able to programmatically add the dates to the schema inside of the addDateHooks method. This isn't exactly the same, but basically, we are programmatically updating the schema object.

Inside of addDateHooks, you could do something like:

backboneModel.prototype.schema = _.defaults(
  backboneModel.prototype.schema || {}, 
  {created_at: 'DateTime', updated_at: 'DateTime'}
);

If you want to get fancy, you could release an npm module like backbone-save-dates so you just have to write:

require('backbone-orm-updated-at')(SomeModel);

In terms of your dates, BackboneORM should convert them to ISO6801 date strings already I believe, but I think your format is slightly different. I think the natural hook fr date serialization in Backbone is toJSON, but it's fine either way.

Underscore has a toArray method for the arguments so you could also write:

return originalSave.apply(this, _.toArray(arguments)); 

but I'm not sure if that is necessary. I've noticed sometimes where nested apply calls with arguments don't work well, but not sure if this is one of those cases.

You could also simplify the data setting like:

this.set('updated_at', now());
this.has('created_at') || this.set('created_at', this.get('updated_at'))

Small tweaks!