Skip to content

Instantly share code, notes, and snippets.

@tblobaum
Created September 22, 2011 09:42
Show Gist options
  • Save tblobaum/1234428 to your computer and use it in GitHub Desktop.
Save tblobaum/1234428 to your computer and use it in GitHub Desktop.
Mongoose Middlewares & patterns for embedded documents without an embedded documents array
// Mongoose single embedded docs with 5 middlewares
var AccountObj = {
id: {type:ObjectId, index: {unique:true}},
fname: String,
lname: String,
email: String,
phone: String
};
var PostObj = {
id: {type:ObjectId, index: {unique:true}},
title: String,
body: String,
time: String
};
var PageObj = {
id: {type:ObjectId, index: {unique:true}},
title: String,
account: AccountObj,
post: PostObj
};
AccountSchema = new Schema(AccountObj);
PostSchema = new Schema(PostObj);
PageSchema = new Schema(PageObj);
AccountSchema.pre('init', function(next){
//do something ...
next();
});
AccountSchema.pre('save', function(next){
this.email = 'example@example.com'; // do something with this
next();
});
PostSchema.pre('init', function(next){
//do something ...
next();
});
PostSchema.pre('save', function(next){
this.title = 'A different title.'; // do something with this
next();
});
PageSchema.pre('init', function(next, doc){
Account.findById(doc.account, function (e, account) {
doc.account = account;
Post.findById(doc.post, function (e, post) {
doc.post = post;
next();
});
});
});
PageSchema.pre('save', function(next){
// swap account model for the id
var id = this._doc.account._id;
//save the account model, which fires it's own middleware
this._doc.account.save();
// reset the account to the id before it is saved
this._doc.account = id;
// same thing, one could repeat this patten to add more models
var id = this._doc.post._id;
this._doc.post.save();
this._doc.post = id;
next();
});
PageSchema.pre('remove', function(next){
var account = false
, post = false;
if (this._doc && this._doc.account) account = {_id:this._doc.account._id};
if (this._doc && this._doc.post) post = {_id:this._doc.post._id};
Account.remove(account, function(e,c) {
console.log(e);
console.log(c);
Post.remove(post, function(e,c) {
console.log(e);
console.log(c);
next();
});
});
});
Mongoose.model('Account', AccountSchema);
Mongoose.model('Post', PostSchema);
Mongoose.model('Page', PageSchema);
Account = Mongoose.model('Account');
Post = Mongoose.model('Post');
Page = Mongoose.model('Page');
var acct = new Account({
fname: 'human',
lname: 'chimp',
email: 'email@github.com'
});
var post = new Post({
title: 'A post title.',
body: 'A comment or post or some such',
});
var page = new Page({
title: 'A page title.',
account: acct,
post: post
});
// Tests! -- save, init, and remove
page.save(function(err){
console.log(err);
Page.findOne({"title": "A page title."}, function(e, doc){
console.log(e);
console.log(doc); // this should have the populated account, post models
doc.remove(function (e, c) { //this finds and removes the account and post models
console.log(e);
console.log(c);
});
});
});
// Overall, a bit of an anti-pattern with too many database queries, but it works... and it was fun
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment