common_dwarf_mongoose v0.1.2
Common Dwarf Mongoose
Mongoose with some synthetic sugar
Common Dwarf Mongoose is a little wrapper around the excellent Mongoose ORM library. It provides some synthetic sugar like attributes and a more ExtJS/Backbone.js inspired way to define database models.
Installation
Installing is very easy, get it from the NPM registry:
npm install common_dwarf_mongoose
Usage
Mongoose.Base is the superclass for all database related models.
It combines creation of a Mongo schema and a mongoose model. Additional it provides some synthetic sugar around this:
Let's say, we want to store a collection of authors in our MongoDB.
(Note: Connect to your MongoDB just like this says )
To use Mongoose.Base require the module:
require 'common_dwarf_mongoose'
Define the model:
class Author extends Mongoose.Base
alias: 'author'
fields:
name : {type : String, index: true}
blog : {type : String, default: "http://blogpost.com"}
alive : {type : Boolean,default: false}
The alias property is used to name the collection. This is done by pluralizing the alias which is inspired by Ruby On Rails in a very simple way:
author => authors
user => users
blog_post => blog_posts
Any options documented from Mongoose are possible with the following deviantions:
- To use ObjectId use Mongoose.ObjectId
- To use 'any' Type (Schema.Types.Mixed) use Mongoose.Mixed
The class takes care about reating a schema and a mongoose model as documented here.
With the addition of synthetic sugar it allows us:
author = new Author()
author.set('name':'Jack Kerouac')
author.set('blog':'www.ontheroad.com')
author.save((err)-> throw err if err)
Mass assignment is not supported at the moment.
Accessing saved authors is also easy. Maybe you know this from ActiveRecord or Backbone.js:
Author.find({},(err,authorDocuments)->
for authorAsDocument in authorDocuments
author = Author.becomesFrom(author)
console.log author.getName()
console.log author.getBlog()
)
(Also supported are #findById and findByOne.)
Notice the last two lines before the parenthesis.
Any attribute you define in fields will be accessible with a get prefix after a model is instantiated and an attribute is assigned.
author.getBlog()
author.getName()
If you define a boolean attribute in fields the getter will be more context understandable:
author.isAlive()
Another option to get an attribute is calling #get(), which is also well know from backbone.js or ExtJs:
author.get('name') #=> 'Jack Kerouac'
To get all attributes at once, use the #attributes property:
author.attributes #=> {name: 'Jack Kerouac', blog: 'www.ontheroad.com'}
If you need a JSON representation of your model's data, you can achieve this with #toJSON() method:
author.toJSON() #=> {'name' : 'Jack Kerouac', 'blog' : 'www.ontheroad.com'}
Plugins
Common Dwarf Mongoose also supports plugins like you know them from mongoose. Adding them to your model is easy as defining fields:
Write a plugin or use an existing one:
lastModified = (schema, options)->
schema.add({ lastMod: Date })
schema.pre('save', (next)->
this.lastMod = new Date
next()
)
schema.path('lastMod').index(options.index) if (options && options.index)
Add the plugin to the model:
class Author extends Mongoose.Base
alias: 'author'
fields:
name : {type : String, index: true}
blog : {type : String, default: "http://blogpost.com"}
alive : {type : Boolean,default: false}
plugins:
plugin: lastModified, config: {index: true}
That's it.
Multiple connections
If you have to handle documents scattered at different databases it would be nice to handle this within the model definition. Unfortunately, adding database names to a common_dwarf_mongoose model is not possible due the fact it is mongoose based. But a solution is to add a connection instance to your model.
personnel_db = mongo.createConnection("mongodb://0.0.0.0/personnel")
tasks_db = mongo.createConnection("mongodb://0.0.0.0/tasks")
class FacilityManager extends Mongoose.Base
alias: 'manager'
fields:
name : { type: String, index: true }
salary : { type: Number }
connection: personnel_db
class Task extends Mongoose.Base
alias: 'task'
fields:
name : { type: String, index: true }
due_to : { type: Date, index:true }
done : { type: Boolean }
Note: If you seperate your database connection handling from defining your models (say other files or modules), connection must be global or otherwise accessable.
Querying
To use #where()
Actor.forWhere()
.where('age').gte(25)
.where('tags').in(['movie', 'music', 'art'])
. # select('name', 'age', 'tags')
.skip(20)
.limit(10)
.asc('age')
.slaveOk()
.hint({ age: 1, name: 1 })
.run(callback)
Aggregating
You can use #count of course.
Mixin support
Common Dwarf Mongoose provides mixin support which is accessible if you require the library:
require 'common_dwarf_mongoose'
Any class which inherits from Mixin.Base could include or extend functionality with JavaScript objects:
Extensions.documentation =
kind:->
"paper"
Extensions.folder =
folderType:->
"extensions"
class A extends Mixin.Base
@include Extensions.documentation
@extend Extensions.folder
class B extends Mixin.Base
@include Extensions.documentation
@extend Extensions.folder
a = new A()
b = new B()
console.log a.kind()
console.log b.kind()
console.log A.folderType()
console.log B.folderType()
Common Dwarf Mongoose provides a global namespace called Extensions which could be used to collect all your mixin modules within a single namespace.
Authors and Contributors
Written by Daniel Schmidt(@dsci), Datenspiel GmbH 2012
The picture above was taken by Quartl.
Support or Contact
Having trouble with Common Dwarf Mongoose? Do not hesitate to open an issue at the Issue Tracker :octocat: .