JedWatson/keystone — pull request #523 by JohnnyEstilles (2014-08-10 03:09:02+00:00)
Title: Adding List 'track' option (replaces #490)

As promised, here's my PR for the List `track` option, which adds plugin that automatically tracks when and who created and last updated an item. This PR replaces #490.

The feature can be enabled for all tracking fields, with all their default names, by setting `track` to `true`.

var List = keystone.List('MyList', { track: true });

I added this as a shortcut to setting `track` to `{ createdAt: true, createdBy: true, updatedAt: true, updatedBy: true}`, which I thought was a bit verbose and probably the most common use case.

You can selectively enabled each tracking field by setting `track` an `object` containing the keys for the desired fields set to `true`. When using this method, fields will default to `false`, so any omitted fields will not be enabled.

var List = keystone.List('MyList, {
track: { createdAt: true, createdBy: true }
});

You can also selective specify custom field names by setting the desired field keys to a string representing the desired name.

var List = keystone.List('MyList, {
track: {
createdAt: true,
createdBy: 'whoCreatedThis',
updatedAt: true,
updatedBy: 'whoUpdatedThis'
}
});

As we agreed in #490, using `List.addPattern('standard meta')` enables the `track` option and maps `createdOn` and `updatedOn` to `createdAt` and `updatedAt` respectively. It also displays a message warning the developer that the feature is now deprecated.

I've also updated the Keystone docs with documentation for the `track` option. I included a caveat pointing out that `createdBy` and `updatedBy` are only updated when adding/updating items via the Admin UI (which uses the `updateHandler()`). I further explained that if developers wish to add/modify items from their own apps they must manually store the currently logged on user in the item prior to calling `.save()`. I used the following example:

var item = new List.model();
item.set({ field1: 'value1', field2: 'value2' });

item._req_user = req.user;

item.save();

This addresses the issue of `._req_user` not being available to `pre` and `post` save hooks when using `.save()`.

Finally, I included a unit test for the feature. I refactored some common code into helper functions and updated the test for the `._req_user` feature to use them as well.

That's it! Comments, suggestions and modifications are always welcome!