Skip to content

Instantly share code, notes, and snippets.

@Tronix117
Created May 10, 2013 10:20
Show Gist options
  • Save Tronix117/5553599 to your computer and use it in GitHub Desktop.
Save Tronix117/5553599 to your computer and use it in GitHub Desktop.
Relational layer over modal for Backbone. Can manage single id or multiple id relations between models. one-to-one, one-to-many, many-to-many, smart selection of id key, or possible to specify it ('through' keyword). Autofetch can also fetch missing related collection models.
###
# Adding relation support to models
Note: Given collections were here Singletons in this project, you can also use instances of collections instead.
relations:
friends: require 'collections/Users' # @get('friends') will return an array of friend if friends_ids or friends_id is an array
store: require 'collections/Store' # @get('store') will return the store object if there is a store_id
subcategories:
through: 'category_ids'
collection: require 'collections/Categories'
customer:
collection: require 'collections/Customers'
autofetch: true # will fetch it, and if found will trigger the 'change' event of the model
For relation items, a callback can be passed: `@get 'customer', (customer)-> #do something`,
it's mainly usefull when autofetch is enabled, the callback will be triggered once the object
has been retrieved from the server.
If it's a collection like `subcategories` in the above exemple, the callback will be triggered once all objects will be retrieved.
###
BaseModel extends Backbone.Model
get: (name, cb)->
# Nothing special to do if no relations have been defined for this key
return super unless r = @relations?[name]
# Retrieve id or ids of model(s) to return, and define collection
ids = (r.through and @get r.through) or @get(name + '_id') or @get(name + '_ids')
collection = r.collection or r
# Ensure that _ids is always an array
_ids = [].concat ids
after_cb = unless cb then (->) else _.after _ids.count, cb
models = []
for id in _ids
# fetch model if not found and autofetch option is enabled
model = collection.get id
if r.autofetch and not model
model = new collection.model id: id
model.fetch success: =>
@trigger 'change'
after_cb models
collection.add model
models.push model
else
models.push model
after_cb models
if typeof ids isnt 'Array' then models[0] else models
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment