17 KiB
TOC
- app
- asteroid
- DataSource
- Model
- Model.validatesPresenceOf(properties...)
- Model.validatesLengthOf(property, options)
- Model.validatesInclusionOf(property, options)
- Model.validatesExclusionOf(property, options)
- Model.validatesNumericalityOf(property, options)
- Model.validatesUniquenessOf(property, options)
- myModel.isValid()
- Model.attachTo(dataSource)
- Model.create([data], [callback])
- model.save([options], [callback])
- model.updateAttributes(data, [callback])
- Model.upsert(data, callback)
- model.destroy([callback])
- Model.destroyAll(callback)
- Model.find(id, callback)
- Model.count([query], callback)
- Remote Methods
- Model.hasMany(Model)
app
app.model(Model)
Expose a Model
to remote clients..
var memory = asteroid.createDataSource({connector: asteroid.Memory});
var Color = memory.createModel('color', {name: String});
app.model(Color);
assert.equal(app.models().length, 1);
app.models()
Get the app's exposed models..
var Color = asteroid.createModel('color', {name: String});
var models = app.models();
assert.equal(models.length, 1);
assert.equal(models[0].modelName, 'color');
asteroid
asteroid.createDataSource(options)
Create a data source with a connector..
var dataSource = asteroid.createDataSource({
connector: asteroid.Memory
});
assert(dataSource.connector());
asteroid.remoteMethod(Model, fn, [options]);
Setup a remote method..
var Product = asteroid.createModel('product', {price: Number});
Product.stats = function(fn) {
// ...
}
asteroid.remoteMethod(
Product.stats,
{
returns: {arg: 'stats', type: 'array'},
http: {path: '/info', verb: 'get'}
}
);
assert.equal(Product.stats.returns.arg, 'stats');
assert.equal(Product.stats.returns.type, 'array');
assert.equal(Product.stats.http.path, '/info');
assert.equal(Product.stats.http.verb, 'get');
assert.equal(Product.stats.shared, true);
DataSource
dataSource.createModel(name, properties, settings)
Define a model and attach it to a DataSource
..
var Color = memory.createModel('color', {name: String});
assert.isFunc(Color, 'all');
assert.isFunc(Color, 'create');
assert.isFunc(Color, 'updateOrCreate');
assert.isFunc(Color, 'upsert');
assert.isFunc(Color, 'findOrCreate');
assert.isFunc(Color, 'exists');
assert.isFunc(Color, 'find');
assert.isFunc(Color, 'findOne');
assert.isFunc(Color, 'destroyAll');
assert.isFunc(Color, 'count');
assert.isFunc(Color, 'include');
assert.isFunc(Color, 'relationNameFor');
assert.isFunc(Color, 'hasMany');
assert.isFunc(Color, 'belongsTo');
assert.isFunc(Color, 'hasAndBelongsToMany');
assert.isFunc(Color.prototype, 'save');
assert.isFunc(Color.prototype, 'isNewRecord');
assert.isFunc(Color.prototype, 'destroy');
assert.isFunc(Color.prototype, 'updateAttribute');
assert.isFunc(Color.prototype, 'updateAttributes');
assert.isFunc(Color.prototype, 'reload');
dataSource.operations()
List the enabled and disabled operations..
// assert the defaults
// - true: the method should be remote enabled
// - false: the method should not be remote enabled
// -
existsAndShared('_forDB', false);
existsAndShared('create', true);
existsAndShared('updateOrCreate', false);
existsAndShared('upsert', false);
existsAndShared('findOrCreate', false);
existsAndShared('exists', true);
existsAndShared('find', true);
existsAndShared('all', true);
existsAndShared('findOne', true);
existsAndShared('destroyAll', false);
existsAndShared('count', true);
existsAndShared('include', false);
existsAndShared('relationNameFor', false);
existsAndShared('hasMany', false);
existsAndShared('belongsTo', false);
existsAndShared('hasAndBelongsToMany', false);
existsAndShared('save', true);
existsAndShared('isNewRecord', false);
existsAndShared('_adapter', false);
existsAndShared('destroy', true);
existsAndShared('updateAttribute', true);
existsAndShared('updateAttributes', true);
existsAndShared('reload', true);
function existsAndShared(name, isRemoteEnabled) {
var op = memory.getOperation(name);
assert(op.remoteEnabled === isRemoteEnabled, name + ' ' + (isRemoteEnabled ? 'should' : 'should not') + ' be remote enabled');
}
Model
Model.validatesPresenceOf(properties...)
Require a model to include a property to be considered valid..
User.validatesPresenceOf('first', 'last', 'age');
var joe = new User({first: 'joe'});
assert(joe.isValid() === false, 'model should not validate');
assert(joe.errors.last, 'should have a missing last error');
assert(joe.errors.age, 'should have a missing age error');
Model.validatesLengthOf(property, options)
Require a property length to be within a specified range..
User.validatesLengthOf('password', {min: 5, message: {min: 'Password is too short'}});
var joe = new User({password: '1234'});
assert(joe.isValid() === false, 'model should not be valid');
assert(joe.errors.password, 'should have password error');
Model.validatesInclusionOf(property, options)
Require a value for property
to be in the specified array..
User.validatesInclusionOf('gender', {in: ['male', 'female']});
var foo = new User({gender: 'bar'});
assert(foo.isValid() === false, 'model should not be valid');
assert(foo.errors.gender, 'should have gender error');
Model.validatesExclusionOf(property, options)
Require a value for property
to not exist in the specified array..
User.validatesExclusionOf('domain', {in: ['www', 'billing', 'admin']});
var foo = new User({domain: 'www'});
var bar = new User({domain: 'billing'});
var bat = new User({domain: 'admin'});
assert(foo.isValid() === false);
assert(bar.isValid() === false);
assert(bat.isValid() === false);
assert(foo.errors.domain, 'model should have a domain error');
assert(bat.errors.domain, 'model should have a domain error');
assert(bat.errors.domain, 'model should have a domain error');
Model.validatesNumericalityOf(property, options)
Require a value for property
to be a specific type of Number
..
User.validatesNumericalityOf('age', {int: true});
var joe = new User({age: 10.2});
assert(joe.isValid() === false);
var bob = new User({age: 0});
assert(bob.isValid() === true);
assert(joe.errors.age, 'model should have an age error');
Model.validatesUniquenessOf(property, options)
Ensure the value for property
is unique..
User.validatesUniquenessOf('email', {message: 'email is not unique'});
var joe = new User({email: 'joe@joe.com'});
var joe2 = new User({email: 'joe@joe.com'});
joe.save(function () {
joe2.save(function (err) {
assert(err, 'should get a validation error');
assert(joe2.errors.email, 'model should have email error');
done();
});
});
myModel.isValid()
Validate the model instance..
User.validatesNumericalityOf('age', {int: true});
var user = new User({first: 'joe', age: 'flarg'})
var valid = user.isValid();
assert(valid === false);
assert(user.errors.age, 'model should have age error');
Asynchronously validate the model..
User.validatesNumericalityOf('age', {int: true});
var user = new User({first: 'joe', age: 'flarg'})
user.isValid(function (valid) {
assert(valid === false);
assert(user.errors.age, 'model should have age error');
done();
});
Model.attachTo(dataSource)
Attach a model to a DataSource.
var MyModel = asteroid.createModel('my-model', {name: String});
assert(MyModel.all === undefined, 'should not have data access methods');
MyModel.attachTo(memory);
assert(typeof MyModel.all === 'function', 'should have data access methods after attaching to a data source');
Model.create([data], [callback])
Create an instance of Model with given data and save to the attached data source..
User.create({first: 'Joe', last: 'Bob'}, function(err, user) {
assert(user instanceof User);
done();
});
model.save([options], [callback])
Save an instance of a Model to the attached data source..
var joe = new User({first: 'Joe', last: 'Bob'});
joe.save(function(err, user) {
assert(user.id);
assert(!err);
assert(!user.errors);
done();
});
model.updateAttributes(data, [callback])
Save specified attributes to the attached data source..
User.create({first: 'joe', age: 100}, function (err, user) {
assert(!err);
assert.equal(user.first, 'joe');
user.updateAttributes({
first: 'updatedFirst',
last: 'updatedLast'
}, function (err, updatedUser) {
assert(!err);
assert.equal(updatedUser.first, 'updatedFirst');
assert.equal(updatedUser.last, 'updatedLast');
assert.equal(updatedUser.age, 100);
done();
});
});
Model.upsert(data, callback)
Update when record with id=data.id found, insert otherwise.
User.upsert({first: 'joe', id: 7}, function (err, user) {
assert(!err);
assert.equal(user.first, 'joe');
User.upsert({first: 'bob', id: 7}, function (err, updatedUser) {
assert(!err);
assert.equal(updatedUser.first, 'bob');
done();
});
});
model.destroy([callback])
Remove a model from the attached data source..
User.create({first: 'joe', last: 'bob'}, function (err, user) {
User.find(user.id, function (err, foundUser) {
assert.equal(user.id, foundUser.id);
foundUser.destroy(function () {
User.find(user.id, function (err, notFound) {
assert(!err);
assert.equal(notFound, null);
done();
});
});
});
});
Model.destroyAll(callback)
Delete all Model instances from data source.
(new TaskEmitter())
.task(User, 'create', {first: 'jill'})
.task(User, 'create', {first: 'bob'})
.task(User, 'create', {first: 'jan'})
.task(User, 'create', {first: 'sam'})
.task(User, 'create', {first: 'suzy'})
.on('done', function () {
User.count(function (err, count) {
assert.equal(count, 5);
User.destroyAll(function () {
User.count(function (err, count) {
assert.equal(count, 0);
done();
});
});
});
});
Model.find(id, callback)
Find instance by id..
User.create({first: 'michael', last: 'jordan', id: 23}, function () {
User.find(23, function (err, user) {
assert.equal(user.id, 23);
assert.equal(user.first, 'michael');
assert.equal(user.last, 'jordan');
done();
});
});
Model.count([query], callback)
Query count of Model instances in data source.
(new TaskEmitter())
.task(User, 'create', {first: 'jill', age: 100})
.task(User, 'create', {first: 'bob', age: 200})
.task(User, 'create', {first: 'jan'})
.task(User, 'create', {first: 'sam'})
.task(User, 'create', {first: 'suzy'})
.on('done', function () {
User.count({age: {gt: 99}}, function (err, count) {
assert.equal(count, 2);
done();
});
});
Remote Methods
example remote method
should allow calling remotely.
request(app)
.get('/users/sign-in?username=foo&password=bar')
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res){
if(err) return done(err);
assert(res.body.$data === 123);
done();
});
Model.beforeRemote(name, fn)
Run a function before a remote method is called by a client..
var hookCalled = false;
User.beforeRemote('*.save', function(ctx, user, next) {
hookCalled = true;
next();
});
// invoke save
request(app)
.post('/users')
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
if(err) return done(err);
assert(hookCalled, 'hook wasnt called');
done();
});
Model.afterRemote(name, fn)
Run a function after a remote method is called by a client..
var beforeCalled = false;
var afterCalled = false;
User.beforeRemote('*.save', function(ctx, user, next) {
assert(!afterCalled);
beforeCalled = true;
next();
});
User.afterRemote('*.save', function(ctx, user, next) {
assert(beforeCalled);
afterCalled = true;
next();
});
// invoke save
request(app)
.post('/users')
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
if(err) return done(err);
assert(beforeCalled, 'before hook was not called');
assert(afterCalled, 'after hook was not called');
done();
});
Remote Method invoking context
ctx.req
The express ServerRequest object.
var hookCalled = false;
User.beforeRemote('*.save', function(ctx, user, next) {
hookCalled = true;
assert(ctx.req);
assert(ctx.req.url);
assert(ctx.req.method);
assert(ctx.res);
assert(ctx.res.write);
assert(ctx.res.end);
next();
});
// invoke save
request(app)
.post('/users')
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
if(err) return done(err);
assert(hookCalled);
done();
});
ctx.res
The express ServerResponse object.
var hookCalled = false;
User.beforeRemote('*.save', function(ctx, user, next) {
hookCalled = true;
assert(ctx.req);
assert(ctx.req.url);
assert(ctx.req.method);
assert(ctx.res);
assert(ctx.res.write);
assert(ctx.res.end);
next();
});
// invoke save
request(app)
.post('/users')
.send({data: {first: 'foo', last: 'bar'}})
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
if(err) return done(err);
assert(hookCalled);
done();
});
Model.hasMany(Model)
Define a one to many relationship..
var Book = memory.createModel('book', {title: String, author: String});
var Chapter = memory.createModel('chapter', {title: String});
// by referencing model
Book.hasMany(Chapter);
Book.create({title: 'Into the Wild', author: 'Jon Krakauer'}, function(err, book) {
// using 'chapters' scope for build:
var c = book.chapters.build({title: 'Chapter 1'});
book.chapters.create({title: 'Chapter 2'}, function () {
c.save(function () {
Chapter.count({bookId: book.id}, function (err, count) {
assert.equal(count, 2);
book.chapters({where: {title: 'Chapter 1'}}, function(err, chapters) {
assert.equal(chapters.length, 1);
assert.equal(chapters[0].title, 'Chapter 1');
done();
});
});
});
});
});