Created
August 8, 2012 13:46
-
-
Save tresbailey/3295135 to your computer and use it in GitHub Desktop.
Generically Persist BackboneJS Objects into MongoDB with NodeJS (coffeescript)
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
mongoose = require 'mongoose' | |
Backbone = require 'backbone' | |
$ = require 'jquery' | |
_ = require('underscore')._ | |
Schema = mongoose.Schema | |
Articles = new Schema | |
identity: Number, | |
order: Number, | |
quick_title: String, | |
full_title: String, | |
last_edited: Number, | |
contributor: [String], | |
content: String, | |
video_link: String, | |
presentation_link: String, | |
question_id: [Number], | |
show_in_chapter: Boolean, | |
summary_text: String, | |
summary_image: String | |
chapters = new Schema | |
order: Number, | |
title: String, | |
articles: [Articles] | |
ArticleB = Backbone.Model.extend {} | |
ArticleCollection = Backbone.Collection.extend | |
model: ArticleB | |
ChapterB = Backbone.Model.extend | |
initialize: () -> | |
this.articles = new ArticleCollection() | |
ChapterCollection = Backbone.Collection.extend | |
model: ChapterB | |
ChapterTop = Backbone.Model.extend | |
initialize: () -> | |
this.chapters = new ChapterCollection() | |
Backbone.Collection.prototype.xport = (opt) -> | |
overall = {} | |
result = [] | |
for model in this.models | |
result.push model.xport() | |
overall['models'] = result | |
overall['id'] = this.id or null | |
overall['cid'] = this.cid or null | |
return overall | |
Backbone.Model.prototype.print = (opt) -> | |
result = {} | |
settings = _({recurse: true}).extend(opt or {}) | |
process = (targetObj, source) -> | |
targetObj.id = source.id or null | |
targetObj.cid = source.cid or null | |
targetObj.attrs = source.toJSON() | |
_.each source, (value, key) -> | |
if settings.recurse | |
if key != 'collection' and source[key] instanceof Backbone.Collection | |
targetObj.collections = targetObj.collections or {} | |
targetObj.collections[key] = {} | |
targetObj.collections[key].models = [] or null | |
targetObj.collections[key].id = source[key].id or null | |
_.each source[key].models, (mod, index) -> | |
process(targetObj.collections[key].models = {}, mod) | |
else if source[key] instanceof Backbone.Model | |
targetObj.models = targetObj.models or {} | |
process( targetObj.models[key] = {}, value) | |
process result, this | |
return result | |
Backbone.Model.prototype.xport = (opt) -> | |
result = {} | |
settings = _({ | |
recurse: true | |
}).extend(opt or {}) | |
result.id = this.id or null | |
result.cid = this.cid or null | |
result.attrs = this | |
for own key, value of this | |
console.log "#{ key }" | |
if key != 'collection' and value instanceof Backbone.Collection | |
this.collections = this.collections or {} | |
result.collections = result.collections or {} | |
result.collections[key] = this[key].xport() | |
else if value instanceof Backbone.Model | |
result.models = result.models or {} | |
result.models[key].xport() | |
return result | |
Backbone.Collection.prototype.mport = (data, silent) -> | |
this.id = data.id or null | |
if this.models? | |
for model in data | |
model_instance = new this.model() | |
model_instance.mport model, silent | |
this.add model_instance | |
return this | |
Backbone.Model.prototype.mport = (data, silent) -> | |
this.id = data.id or null | |
if this.cid? | |
collections = {} | |
for own key, value of data?.toJSON?() | |
if value?.push? | |
sub_inst = this[key] | |
collections[key] = {} | |
sub_inst.mport value, silent | |
collections[key].models = sub_inst | |
this.set {attrs: data, collections: collections}, silent | |
return this |
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
inserts = () -> | |
mongoose.connect 'mongodb://localhost/article' | |
chapters = mongoose.model 'chapters', chapters | |
Articles = mongoose.model 'Articles', Articles | |
instance = new chapters() | |
instance.order = 123 | |
article = new Articles() | |
article.identity = 1 | |
article.full_title = "Wind in the Willows" | |
instance.articles.push article | |
article = new Articles() | |
article.identity = 2 | |
article.full_title = "Sleepy Hollow" | |
instance.articles.push article | |
instance.save (err) -> | |
if err? | |
console.log "Errors saving with #{ err }" | |
inserts() | |
retrieve = () -> | |
mongoose.connect 'mongodb://localhost/article' | |
myModel = mongoose.model 'chapters', chapters | |
myModel.find {}, (err, docs) -> | |
all_chaps = new ChapterCollection() | |
all_chaps.mport docs, {silent: true} | |
console.log "MPORTed backbone: #{ JSON.stringify all_chaps }" | |
console.log "XPORTed backbone: #{ JSON.stringify all_chaps.xport() }" | |
retrieve() | |
simple = () -> | |
chapter = new ChapterB {name: 'Tres', order: 123 } | |
coll = new ChapterCollection [chapter] | |
chapter = new ChapterB {name: 'ada', order: 123 } | |
coll.add chapter | |
top = new ChapterTop() | |
top.chapters.add chapter | |
console.log "xport of basic object from hand #{ JSON.stringify top.xport() }" | |
console.log "print of basic object from hand #{ JSON.stringify top.print() }" | |
simple() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The first file uses a similar technique to Capsule JS for being able to serialize BackboneJS objects between client and server. Actually, the print method of Model is just the xport() method that andyet originally posted. This version uses different approaches for Models and Collections to store only data objects into a MongoDB collection, without the backbonejs metadata with xport() and then loads the metadata for those objects from MongoDB using mport().
The second file is incomplete. It has been all in a single file on my system, but I separated them for the sake of readability. To use this example, either paste the second file into the bottom of the first, or modify the first to share the changes of the Backbone classes, and import the necessary classes into the second file.