The main purpose of this package is to retain revisions of collection documents and allow for the restore of those revisions.
Note: This package has been decaffeinated which makes it suitable for Meteor 1.6.1, where coffeescript
got a major update.
- Saves a revision of the entire document when updates are made to it.
- Revisions are stored within a field of the document, so no extra publications or subscriptions are needed to get the revisions.
- Can specify how many revisions to keep per document, or keep unlimited
- Can specify to not create revisions for updates made within a certain amount of time since the last revision (helpful for autoform with autosave triggering multiple updates)
- Prune foregoing revisions upon restore
- Callback function that provides two parameters - the revision and modifier objects before the collection update. Returning false in the callback will cancel the creation of a revision.
meteor add simonsimcity:collection-revisions
After you define your collection with something like:
Collection = new Mongo.Collection("collection");
You can use CollectionRevisions a few different ways: (Foo is our collection)
Foo.attachCollectionRevisions();
This will use all defaults, either by your code in CollectionRevisions.defaults or the package defaults.
CollectionRevisions.defaults.keep = 10;
CollectionRevisions.defaults.debug = true;
... define whatever options you want to override the package defaults
These will be used for all collections you attach the CollectionRevisions to.
CollectionRevisions.Foo = {
keep:10
ignoreWithin: 60000
... define whatever options you want to override the global or package defaults
}
Foo.attachCollectionRevisions(CollectionRevisions.Foo);
Option | Default | Description |
---|---|---|
field | 'revisions' | name of the field which will hold the document's revisions within itself String |
lastModifiedField | 'lastModified' | Name of the field storing the date / time the document was last modified String |
ignoreWithin | 0 | If an update occurs within this amount of milliseconds since the last update, a new revision will not be created. Number |
keep | true | Specify a number if you wish to only retain a limited number of revisions per document. True = retain all revisions. Number or Boolean |
prune | false | Will delete the restored revision and all subsequent revisions. Boolean |
debug | false | Turn to true to get console debug messages. |
callback | undefined | Allows custom code to be executed against the revision and modifier objects before updating the collection. |
A revision can be restored by calling CollectionRevisions.restore from either the client, server, or both. It will follow the same allow / deny permissions for an update, or use your own permissions and call CollectionRevisions.restore within a method call. If you want the simulation to run correctly on the client, the document needs to be published and the revisions field present.
CollectionRevisions.restore(collection, documentId, revision, callback);
Parameter | Type | Description |
---|---|---|
collection | Object | This is the object of your collection |
documentId | String | the _id of the document you want to restore |
revision | revisionId or Object | Simplest form is to provide the revisionId stored within the revision, if you want to use specific data to restore, you can provide the revision object, overriding any fields you want to update the document to. |
callback | Function | Callback function that is executed when the update is completed. Takes two parameters: function(error, result) . Refer to the node mongodb driver documentation. |
Example template code: (bootstrap)
*Inside of Document Context*
<ul class="list-group">
<li class='list-group-item'>
<div class='col-xs-12 col-sm-6'>
{{moment lastModified 'dddd, MMMM Do YYYY, h:mm:ss a'}}
</div>
<div class='col-xs-12 col-sm-6'>
<button type="button" class="btn btn-default btn-success btn-xs pull-right">
Current Revision
</button>
</div>
<div class='clearfix'></div>
</li>
{{#each revisions}}
<li class='list-group-item'>
<div class='col-xs-12 col-sm-6'>
{{moment lastModified 'dddd, MMMM Do YYYY, h:mm:ss a'}}
</div>
<div class='col-xs-12 col-sm-6'>
<button type="button" class="btn btn-default btn-primary btn-xs pull-right revertFoo">
<i class="fa fa-undo"></i> Revert
</button>
</div>
<div class='clearfix'></div>
</li>
{{/each}}
</ul>
This is also using a global helper I have for moment:
Template.registerHelper('moment', function(date, format) {
date = moment(date);
return date.format(format);
});
Example template event code where Foo
is the collection:
Template.fooRevisions.events({
'click .revertFoo'(e,t) {
// get the foo document _id
const foo = Template.parentData();
// restore the revision
CollectionRevisions.restore(Foo, foo._id, this.revisionId);
}
});
Callback format is function(revision, modifier)
.
This can be used to make changes to the revision before it is saved. Example:
CollectionRevisions.Employee = {
callback: function(revision, modifier) {
// This allows a custom field be inserted into the revision
revision.dateTermination = modifier.$set.dateEffective;
}
}
This can also be used to allow custom logic that negates creating a revision by returning false:
CollectionRevisions.Employee = {
callback: function(revision, modifier) {
// Do no create a revision if the effective date did not change
if(revision.dateEffective.getTime() === modifier.$set.dateEffective.getTime())
return false;
}
}
This package will not create revisions for Documents when an update is for multiple documents (multi=true)