Skip to content

Instantly share code, notes, and snippets.

@kristianmandrup
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristianmandrup/8952239 to your computer and use it in GitHub Desktop.
Save kristianmandrup/8952239 to your computer and use it in GitHub Desktop.
Racer model abstraction
crud.Delete = new Class(RacerSync,
initialize: (@context) ->
@callSuper!
@getter = new Models.Get @context
extend:
create: (collection, ids) ->
new @ collection: collection, ids: ids
# validation not needed on delete!
mw-stack: ->
@create-stack 'authorize-mw', 'racer-mw'
one: ->
@perform 'del', @getter.one!
# delete array
selected: ->
selection @getter.selected!
selection: (list) ->
list.each (item) ->
@one item._id
all: ->
model.destroy!
)
crud.Get = new Class(RacerSync,
include: Models.Utils.Getter
extend:
create: (collection, ids) ->
new @ collection: collection, ids: ids
# validation not needed
# must decorate loaded model
mw-stack: ->
@create-stack 'authorize-mw', 'racer-mw', 'decorate-mw'
one: (id) ->
id ||= @id
throw Error "No id set for #{@collection}" unless id
@res = @perform 'at', id
all: ->
@res = @perform 'get'
# allow combination such as own selected, f.ex via passing generator function
these: (ids) ->
ids ||= @ids
return @all! unless _.is-type 'Array', ids
@res = model.query _id: {$in: ids}
exec: (select) ->
@callSuper action: 'read', data: @[select], collection: @collection
)
crud.Set = new Class(RacerSync,
extend:
create: (collection, items) ->
new @ collection: collection, items: items
# marshal-mw
# filters any local data that should not be stored (depending on context)
# similar to decorator
# should be used after validation before racer-mw
mw-stack: ->
@create-stack 'authorize-mw', 'validate-mw', 'marshal-mw', 'racer-mw'
one: ->
@perform 'set', @item
# should be generator function to be used on
own: (fun, key) ->
@my-own(@[fun], @item)
# push array
many: ->
@perform 'set', @items
)
crud.Crud = new Class(
initialize (@collection) ->
@model = app.model
extend:
create: (args) ->
# new @
ctx: (ctx) ->
lo.extend {collection: @collection}, ctx
factory: ->
name = arguments.first
switch typeof arguments
case 'object'
new crud[name] @ctx(arguments)
default
crud[name].create @collection, arguments
get: ->
factory 'Get', arguments
set: ->
factory 'Set', arguments
delete: ->
factory 'Delete', arguments
)
crud = (collection) ->
new crud.Crud collection
crud('users').get(id).one
crud('users').get!.one(id)
users = crud('users')
users.get!.one(id)
users.get!.by(name: name).first
users.get!.by(name: name).all
# See authorize-mw and validator-mw etc. (on my github: kristianmandrup) for real functioning middleware code!
# The following are mainly some ideas for integration with Angular.js and Racer.js
# The code is written in LiveScript, very similar to CoffeeScript (only much better!!)
# see http://livescript.net
Class = require('jsclass/src/core').Class
Module = require('jsclass/src/core').Module
Module = require('jsclass/src/core').Hash
_ = require 'prelude-ls'
racer = require 'racer'
middleware = require 'middleware'
Middleware = middleware.Middleware
# https://github.com/kristianmandrup/authorize-mw
authorize-mw = require('authorize-mw').AuthorizeMw
# https://github.com/kristianmandrup/validator-mw
validate-mw = require('validator-mw').ValidateMw
# TODO: fix this!
store = racer.store
app ||= {}
app.model = store.createModel!
crud =
utils : void
# model.query returns and abstract query. You have to pass it as argument to model.subscribe or model.fetch to get the results. Try this:
# query = model.query 'users', where: {name: 'Lars'}
# model.subscribe query, (err, users) ->
# console.log users.get()
crud.utils.Getter =
get-one: ->
@res.get!
get-all: ->
@res.fetch (err) ->
throw Error "Error: Get.one #{err}" if err
items.get!
crud.RacerSync = new Class(
initialize: (@context) ->
unless _.is-type 'Object', @context
throw Error "Context object must be a Hash, was: #{@context}"
@model = @context.model || app.model
throw Error "Must take a collection hash argument" unless @context.collection
@collection = @context.collection
@ids = @context.ids
@id = @context.id || @ids.first
@items = @context.items
@item = @context.item || @items.first
current-user: ->
# the model of the session user
@user ||= @model.get '_session.user'
racer-middleware: ->
@mw ||= new Middleware('model').use mw-stack!
mw-stack: ->
new Hash
create-stack: (names) ->
stack = {}
names.each (name) ->
stack[name] = middlewares[name]
stack
# hash
stack: (mws) ->
lo.extend @call-super, mws
# TODO
stack-before: (mws) ->
item-path: ->
@spath ||= @collection + '.' + @item
# generator function to be used on some other query
own: (query, args) ->
# own-key = args.key || @owner-key
own-key = @owner-key
lo.extend @[query](args), "#{own-key}": @current-user!.id
perform: (act, items) ->
switch typeof items
case 'array'
items.each (item) ->
@perform act, item
case 'string'
@model[act] @item-path
case void
@model[act] @collection
default
throw Error "Unknown type of item: #{items} to #{act} on"
exec: (args) ->
@racer-middleware.run args
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment