Skip to content

Instantly share code, notes, and snippets.

@ggoodman
Created November 30, 2011 18:37
Show Gist options
  • Save ggoodman/1410192 to your computer and use it in GitHub Desktop.
Save ggoodman/1410192 to your computer and use it in GitHub Desktop.
Declarative model/collection system in CoffeeScript
###
# Currently based on work by Thomas Parslow
# See: https://gist.github.com/1396231
###
lumbar =
version: "0.0.1"
class lumbar.Model
@field: (name, options) ->
@fields ?= {}
@fields[name] = options || {}
@has_many: (klass, options) ->
options ?= {}
options.klass = klass
options.as ?= klass.name.toLowerCase() + 's'
@collections ?= {}
@collections[options.as] = options
constructor: (attributes) ->
@attributes = {}
# Copy in attributes passed in or defaults from the fields as appropriate
for name, options of @constructor.fields
# Defaults can be specified as values or as functions
@attributes[name] = attributes?[name] || if (isFunction(options.default)) then options.default() else options.default
# Set up collections
for name,options of @constructor.collections
@[name] = new Collection(@, options)
@listeners = {}
# Events
bind: (event, listener) =>
(@listeners[event] ?= []).push(listener)
emit: (event, args...) =>
listener(args...) for listener in @listeners[event] if @listeners[event]
# Getters and setters
get: (name) =>
@attributes[name]
set: (name, value) =>
setAttribute = (name, value)
field = @constructor.fields[name]
throw Error('Trying to set an non-existent property!') if not field
# Ignore a re-setting of the same value
return if value == @get(name)
@attributes[name] = value
# Emit change events!
@emit('change', name, value)
@emit("change:#{name}", value)
hash = {}
if _.isObject(name) then _.extend(hash, name)
else hash[name] = value
setAttribute(name, value) for name, value of hash
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment