Model relationships plugin for Mongoose
... because sometimes embedded documents aren't enough.
A plugin for Mongoose adding a simple syntax for model relationships and providing useful helpers to empower them.
This is an early release with limited functionalities. I'm looking for feedback on the API and features (been exploring a few different solutions, nothing's impossible!).
I'm inspiring from various libraries in Ruby I've used throughout the years. Might not be your cup of tea.
First, npm install mongo-relation.
Add relationships to your schema through either hasMany, belongsTo or habtm (has and belongs to many).
ModelName is the name of the Model.options
through if you want to specify what path to use for the relationship. Else the path will be created for you by pluralizing the ModelName.dependent takes either "delete" or "nullify" and indicated what to do when the element is removed from the parent's through array.var mongoose = require'mongoose';require'mongo-relation'; YourSchemahasMany'ModelName' through: 'PathName' dependent: 'delete|nullify';
It's good to take note that for "has and belongs to many" type relationships, the dependent option only deletes the reference, not the actual referenced document.
UserSchemahasMany'Post' dependent: 'delete'; // uses the 'author' path for the relation PostSchemabelongsTo'User' through: 'author';
PostSchemahabtm'Category';CategorySchemahabtm'Post';
Every Document that has their Schema plugged with mongo-relation has access to the following methods.
Let's use this starting point:
var mongoose = require'mongoose';require'mongo-relation'; // UserSchema stores an Array of ObjectIds for posts var UserSchema = posts: mongooseSchemaObjectId; // PostSchema stores an ObjectId for the author var PostSchema = title : String author : mongooseSchemaObjectId; // Attach the plugin UserSchemahasMany'Post';PostSchemabelongsTo'User' through: 'author'; var User = mongoosemodel'User' UserSchema Post = mongoosemodel'Post' PostSchema;
Takes care of creating the child document and the links between it and the parent document.
objs representation of the child document(s) to createcallback (optional) function returning an error if any, the new parent document and the created post(s)Example:
var user = ; userpostscreate title: "Mongoose, now with added love through relationships!" // user.posts.length === 1 // post.title === "Mongoose, now with added love through relationships!" ; // Using an `Array` userpostscreate title: "Not too imaginative post title" title: "... a tad more imaginative post title" // user.posts.length === 3 // posts.length == 2 // posts[0] instanceof Post ;
Instantiates a child document, appends its reference to the parent document and returns the child document. Does not save anything.
obj representation of the child document(s) to createExample:
var post = userpostsbuildtitle: "Just instantiating me";// post.author === user._id
Allows pushing of an already existing document into the parent document. Creates all the right references.
Works with either a saved or unsaved document.
The parent document is not saved, you'll have to do that yourself.
child document to push.callback called with an error if any and the child document w/ references.Example:
var post = ; userpostsappendpost // post.author === user._id // user.posts.id(post._id) === post._id ;
Just like Array.prototype.concat, it appends an Array to another Array
child document to push.callback called with an error if any and the child document w/ references.Example:
var posts = ; userpostsconcatposts // `posts` is an `Array` of `Document` // each have its author set to `user._id` ;
It's the same as a Mongoose.Query. Only looks through the children documents.
See Mongoose.Query for the params
Example:
userpostsfindtitle: "Not too imaginative post title" // posts.length === 1 // posts[0].author == user._id // posts[0].title == "Not too imaginative post title"; ;
Some sugary syntax to populate the parent document's child documents.
fields (optional) you want to get back with each child documentcallback called with an error and the populate documentExample:
userpostspopulate // user.posts.length === 2 ;
Depending on the dependent option, it'll either delete or nullify the
id of the document to removecallback (optional) called after the deed is done with an error if any and the new parent document.Example:
userpostsremoveuserposts0_id // The post will either be delete or have its `author` field nullified ;
Mongo-Relation uses Mocha with Should. Tests are located in ./test and should be ran with the make test command.