diff --git a/graviton.js b/graviton.js index 3063184..3b9c1e0 100644 --- a/graviton.js +++ b/graviton.js @@ -10,6 +10,20 @@ Meteor.startup(function() { // convenience Meteor.Collection.prototype.all = ManyRelation.prototype.all; +// does an insert but builds a model first, returns the model instead of an id +Meteor.Collection.prototype.create = function(obj, callback) { + var model = this.build(obj); + var id; + if (callback) { + model.setId(this.insert.call(this, model.attributes, function(err, res) { + callback(err, model); + })); + } else { + model.setId(this.insert.call(this, model.attributes)); + } + return model; +}; + // use a period-delimited string to access a deeply-nested object Graviton.getProperty = function(obj, string) { var arr = string.split("."); @@ -49,6 +63,8 @@ Graviton.define = function(collectionName, options) { return new Cls(collectionName, obj, options); }; + options.model = model; + var colName = (options.persist) ? collectionName : null; var collection = new Meteor.Collection(colName, { @@ -72,8 +88,7 @@ Graviton.define = function(collectionName, options) { return mdl; }; this._collections[collectionName] = collection; - collection._model = model; - collection._name = options.name || collectionName; + collection._graviton = options; return collection; }; diff --git a/lib/model.js b/lib/model.js index 7c54fe6..3addb98 100644 --- a/lib/model.js +++ b/lib/model.js @@ -38,12 +38,12 @@ Model = function(collectionName, obj, options) { // for creating a custom class to user for model transforms Model.extend = function(proto) { var self = this; - var o = function(collectionName, obj, options) { + var Model = function(collectionName, obj, options) { self.call(this, collectionName, obj, options); }; - o.prototype = _.extend({}, this.prototype, proto); - o.extend = this.extend; - return o; + Model.prototype = _.extend({}, this.prototype, proto); + Model.extend = this.extend; + return Model; }; Model.prototype.get = function(key) { @@ -51,19 +51,40 @@ Model.prototype.get = function(key) { }; Model.prototype.set = function(key, value) { - return Graviton.setProperty(this.attributes, key, value); + if (_.isObject(key)) { + for (var k in key) { + this.set(k, key[k]); + } + return this; + } + Graviton.setProperty(this.attributes, key, value); + return this; +}; + +Model.prototype.setId = function(id) { + this._id = id; + this.set('_id', id); }; Model.prototype.plain = function() { return _.clone(this.attributes); }; -Model.prototype.save = function() { - if (this._id) { - this._collection.update(this._id, {$set: _.omit(this.attributes, '_id')}); - } else { +// insert a doc if it has no _id +Model.prototype.persist = function() { + if (!this._id) { this._id = this._collection.insert(this.attributes); this.set("_id", this._id); + return true; + } + return false; +}; + +// insert or update +// TODO: track the attributes that have changed and only update those +Model.prototype.save = function() { + if (!this.persist()) { + this._collection.update(this._id, {$set: _.omit(this.attributes, '_id')}); } return this; -}; \ No newline at end of file +}; diff --git a/lib/relations.js b/lib/relations.js index dcff839..199d24f 100644 --- a/lib/relations.js +++ b/lib/relations.js @@ -16,10 +16,7 @@ Relation.prototype.build = function(obj) { // inserts model if it doesn't have an id - typically called by add Relation.prototype.persist = function(model) { model = this.build(model); - if (!model._id) { - model._id = this._collection.insert(model.attributes); - model.set('_id', model._id); - } + model.persist(); return model; };