Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Mongoose with some synthetic sugar.
CoffeeScript JavaScript
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib Add support to use different databases
tests
.gitignore Add support to use different databases
Readme.mdown Add support to use different databases
connection.mdown first commit since extracting to a module
index.js
package.json

Readme.mdown

Common Dwarf Mongoose

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: .

Something went wrong with that request. Please try again.