Add support for nesting schema

This commit is contained in:
Raymond Feng 2013-07-11 14:24:47 -07:00
parent 049f4c0c38
commit 194f68468a
3 changed files with 81 additions and 8 deletions

View File

@ -0,0 +1,21 @@
var ModelBuilder = require('../../jugglingdb').ModelBuilder;
var modelBuilder = new ModelBuilder();
// simplier way to describe model
var User = modelBuilder.define('User', {
name: String,
bio: ModelBuilder.Text,
approved: Boolean,
joinedAt: Date,
age: Number,
address: {
street: String,
city: String,
state: String,
zipCode: String,
country: String
}
});
var user = new User({name: 'Joe', age: 20, address: {street: '123 Main St', 'city': 'San Jose', state: 'CA'}});
console.log(user);

View File

@ -107,10 +107,13 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
properties = properties || {};
settings = settings || {};
buildSchema(className, properties);
this.buildSchema(className, properties);
// every class can receive hash of data as optional param
var ModelClass = function ModelConstructor(data, schema) {
var ModelClass = function ModelConstructor(data, schema) {
if(!(this instanceof ModelConstructor)) {
return new ModelConstructor(data, schema);
}
ModelBaseClass.apply(this, arguments);
if(!this.schema) {
hiddenProperty(this, 'schema', schema || this.constructor.schema);
@ -413,13 +416,13 @@ function defineReadonlyProp(obj, key, value) {
* @param type The type string, such as 'number', 'Number', 'boolean', or 'String'. It's case insensitive
* @returns {Function} if the type is resolved
*/
function getSchemaType(type) {
ModelBuilder.prototype.getSchemaType = function(type) {
if (!type) {
return type;
}
if (Array.isArray(type) && type.length > 0) {
// For array types, the first item should be the type string
var itemType = getSchemaType(type[0]);
var itemType = this.getSchemaType(type[0]);
if (typeof itemType === 'function') {
return [itemType];
}
@ -435,10 +438,16 @@ function getSchemaType(type) {
} else if (type.constructor.name == 'Object') {
// We also support the syntax {type: 'string', ...}
if (type.type) {
return getSchemaType(type.type);
return this.getSchemaType(type.type);
} else {
if(!this.anonymousTypesCount) {
this.anonymousTypesCount = 1;
}
return this.define('AnonymousType' + this.anonymousTypesCount, type, {idInjection: false});
/*
console.error(type);
throw new Error('Missing type property');
*/
}
} else if('function' === typeof type ) {
return type;
@ -453,10 +462,10 @@ function getSchemaType(type) {
* @param associations An array of associations between models
* @returns {*}
*/
function buildSchema(name, properties, associations) {
ModelBuilder.prototype.buildSchema = function(name, properties, associations) {
for (var p in properties) {
// console.log(name + "." + p + ": " + properties[p]);
var type = getSchemaType(properties[p]);
var type = this.getSchemaType(properties[p]);
if (typeof type === 'string') {
// console.log('Association: ' + type);
if (Array.isArray(associations)) {
@ -512,7 +521,7 @@ ModelBuilder.prototype.buildModels = function (schemas) {
var associations = [];
for (var s in schemas) {
var name = schemas[s].name;
var schema = buildSchema(name, schemas[s].properties, associations);
var schema = this.buildSchema(name, schemas[s].properties, associations);
var model = this.define(name, schema, schemas[s].options);
models[name] = model;
}

View File

@ -38,6 +38,49 @@ describe('ModelBuilder define model', function () {
done(null, User);
});
it('should be able to define nesting models', function (done) {
var modelBuilder = new ModelBuilder();
// simplier way to describe model
var User = modelBuilder.define('User', {
name: String,
bio: ModelBuilder.Text,
approved: Boolean,
joinedAt: Date,
age: Number,
address: {
street: String,
city: String,
state: String,
zipCode: String,
country: String
}
});
// define any custom method
User.prototype.getNameAndAge = function () {
return this.name + ', ' + this.age;
};
modelBuilder.models.should.be.a('object').and.have.property('User', User);
modelBuilder.definitions.should.be.a('object').and.have.property('User');
var user = new User({name: 'Joe', age: 20, address: {street: '123 Main St', 'city': 'San Jose', state: 'CA'}});
console.log(user);
User.modelName.should.equal('User');
user.should.be.a('object').and.have.property('name', 'Joe');
user.should.have.property('name', 'Joe');
user.should.have.property('age', 20);
user.should.not.have.property('bio');
user.should.have.property('address');
user.address.should.have.property('city', 'San Jose');
user.address.should.have.property('state', 'CA');
done(null, User);
});
});