Created
April 15, 2012 01:42
-
-
Save boutell/2389267 to your computer and use it in GitHub Desktop.
Guarantee short yet unique slugs for any model
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Extend any Mongoose model that has a unique index on a 'slug' field so that | |
// if a unique index error occurs on 'slug', a random digit is added to the slug | |
// and the save operation is retried until it works. This is concurrency-safe even | |
// if you have lots of inserts going on from multiple machines etc. | |
// | |
// By Tom Boutell, [email protected] | |
// | |
// NOTE: YOU MUST HAVE THIS PULL REQUEST... https://github.com/LearnBoost/mongoose/pull/837 | |
// | |
// (As of this writing that commit is not in LearnBoost/mongoose yet.) | |
// | |
// Here's how to use it: | |
// Make your model the usual way | |
// var MediaItem = mongoose.model('MediaItem', mediaItemSchema); | |
// Call my function to install the extensible slug behavior | |
// modelExtendSlugOnUniqueIndexError(MediaItem); | |
// ALSO: note that it is also very important to make sure your indexes have really | |
// been applied before you try to do things like inserts! Otherwise you won't get | |
// your unique index error until it is too late. | |
// MediaItem.on('index', function() | |
// { | |
// nowICanSafelyInsertThings(); | |
// }); | |
// Call this function with a model object to install the automatic slug extension behavior | |
function modelExtendSlugOnUniqueIndexError(model) | |
{ | |
// Stash the original 'save' method so we can call it | |
model.prototype.saveAfterExtendSlugOnUniqueIndexError = model.prototype.save; | |
// Replace 'save' with a wrapper | |
model.prototype.save = function(f) | |
{ | |
var self = this; | |
// Our replacement callback | |
var extendSlugOnUniqueIndexError = function(err, d) | |
{ | |
if (err) | |
{ | |
// Spots unique index errors relating to the slug field | |
if ((err.code === 11000) && (err.err.indexOf('slug') !== -1)) | |
{ | |
self.slug += (Math.floor(Math.random() * 10)).toString(); | |
self.save(extendSlugOnUniqueIndexError); | |
return; | |
} | |
} | |
// Not our special case so call the original callback | |
f(err, d); | |
}; | |
// Call the original save method, with our wrapper callback | |
self.saveAfterExtendSlugOnUniqueIndexError(extendSlugOnUniqueIndexError); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment