On Github NicholasBoll / scheming-presentation
by Nicholas Boll
Scheming = require('Scheming')
User = Scheming.create 'User',
name :
type : String
required : true
email :
type : String,
required : true
validate : (val) ->
if val.match('@')
return true
else
return 'An email address must have an @ symbol!'
birthday : Date
password :
type : String
setter : (val) ->
return md5(val)
Group = Scheming.create 'Group',
name : String
dateCreated : {type : Date, default : -> Date.now()}
users : [User]
jane = new User
email : 'jane.gmail.com'
birthday : '9/14/86'
password : 'p@$$w0rd!'
console.log Person.validate jane
# {name : 'Field is required.', email: 'An email address must have an @ symbol!'}
jane.name = 'jane'
jane.email = 'jane@gmail.com'
console.log Person.validate jane
# null
Car = Schema.create
make : String
model : String
Person = Schema.create
name : String
car : Car
mark = new Person {name : 'mark'}
# Explicit construction and assignment
# At the time of assignment, civic is already an instance of Car
# so the Car constructor will not be invoked a second time
civic = new Car {make : 'honda', model : 'civic'}
mark.car = civic
# Implicit construction
# At the time of assignment, the value is a plain object. Therefore
# the object is passed to the Car constructor (or in strict mode,
# an error is thrown)
mark.car = {make : 'toyota', model : 'corolla'}
mark.car instanceof Car # true
Person = Scheming.create
name :
type : String
validate : [
-> return "Error number one"
-> throw new Error "Error number two"
-> return true
-> return false
]
bill = new Person()
errors = Person.validate bill
# returns null, because bill object does not have a name defined, and name is not required
bill.name = 'bill'
errors = Person.validate bill
# {name : ["Error number one", "Error number two", "Validation error occurred."]}
Person = Scheming.create 'Person',
name : String
age : Number
mother :
type: 'Schema:Person'
default: {} # create implicit model - otherwise will default to undefined
friends : ['Schema:Person']
lisa = new Person()
# Sync changes are rolled up
lisa.name = 'a'
lisa.name = 'b'
lisa.name = 'lisa'
# Async change resolution
lisa.watch 'name', (newVal, oldVal) ->
# this listener is called once
newVal == 'lisa'
oldVal == undefined
lisa.mother.name = 'jane'
# Deep watch
lisa.watch 'mother', (newVal, oldVal) ->
newVal.name == 'jane'
oldVal.name == undefined