Skip to content

Instantly share code, notes, and snippets.

@craigspaeth
Last active October 6, 2015 21:38
Show Gist options
  • Save craigspaeth/3057320 to your computer and use it in GitHub Desktop.
Save craigspaeth/3057320 to your computer and use it in GitHub Desktop.
Lightweight Backbone Relations Mixin
#
# Wraps `get` and `set` to wrap raw data with instances of models. Also wraps `toJSON`
# to give better serialized output.
# mixin with _.extend @prototype, Backbone.Relations
#
# e.g.
#
# class Paws extends Backbone.Collection
# class Dog extends Backbone.Model
# _.extend @prototype, Backbone.Relations
#
# relations: ->
# paws: Paws
#
# dog = new Dog { paws: [{ toes: 5 }] }
# dog.get('paws') # Returns a collection
#
Relations = ->
Relations::get = (attr) ->
@_relationCache ?= {}
_super = Backbone.Model::get.call @, attr
klass = @relations()[attr]
if klass?
unless @_relationCache[attr]?
isBackboneClass = _super?.cid or _super?.models
instance = @_relationCache[attr] = if isBackboneClass then _super else new klass _super
instance.parent = @
else
instance = @_relationCache[attr]
instance
else
_super
Relations::set = ->
Backbone.Model::set.apply @, arguments
return @ unless @_relationCache?
if _.isObject arguments[0]
delete @_relationCache[key] for key, val of arguments[0]
else if _.isString arguments[0]
delete @_relationCache[arguments[0]]
@
Relations::parse = (res) ->
return res unless @attributes?
for key, klass of @relations()
continue unless klass? and res[key]
@get(key)[if klass::model? then 'reset' else 'set'] res[key]
delete res[key]
res
Backbone.Relations = Relations.prototype
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment