|
'use strict'; |
|
|
|
|
|
|
|
const Waterline = require('waterline'); |
|
const _ = require('underscore'); |
|
const sailsMemoryAdapter = require('sails-memory'); |
|
|
|
var BaseModel = Waterline.Collection.extend({ |
|
connection: 'default', |
|
pubsubModule: null, |
|
attributes: { |
|
displayName: function displayName() { |
|
// Appears there is no way to get to the attribute definitions from an instance. |
|
var firstString = _.first(_.compact(_(this).pairs().map(([key, value]) => { if (!_.contains(['name', 'label', 'id', 'createdAt', 'updatedAt'], key) && _.isString(value)) return key }))); |
|
return this[firstString]; |
|
} |
|
}, |
|
afterCreate: function (record, next) { |
|
console.log('BaseModel: here afterCreate'); |
|
if(this.pubsubModule){ |
|
this.pubsubModule.emitModelEvent(this.getEventType('create'), record); |
|
} |
|
next() |
|
}, |
|
|
|
afterUpdate: function(record, next) { |
|
console.log('BaseModel: here afterUpdate'); |
|
if(this.pubsubModule){ |
|
this.pubsubModule.emitModelEvent(this.getEventType('update'), record); |
|
} |
|
next() |
|
}, |
|
|
|
afterDestroy: function(record, next){ |
|
if(this.pubsubModule){ |
|
this.pubsubModule.emitModelEvent(this.getEventType('destroy'), record); |
|
} |
|
|
|
next(); |
|
}, |
|
getEventType: function(action){ |
|
return this.identity + ':' + action; |
|
} |
|
}); |
|
|
|
BaseModel.extend = function(protoProps, staticProps) { |
|
// Waterline wants each model to have its own connection property, rather than inheriting |
|
if (protoProps.connection === undefined) { |
|
protoProps.connection = this.prototype.connection |
|
} |
|
// Waterline wants each model to have its own attributes property, we want to combine |
|
if (protoProps.attributes === undefined) { |
|
protoProps.attributes = {} |
|
} |
|
|
|
['afterCreate', 'beforeCreate', 'afterUpdate', 'beforeUpdate'].map(wrapBaseMethod); |
|
function wrapBaseMethod(method){ |
|
var _ac = protoProps[method]; |
|
if(_ac){ |
|
protoProps[method] = function(record, next){ |
|
var self = this; |
|
var wrap = function(err){ |
|
if(err) next(err); |
|
else self.constructor.__super__[method](record, next); |
|
}; |
|
_ac.call(protoProps, record, wrap); |
|
} |
|
} |
|
} |
|
|
|
|
|
protoProps.attributes = _.extend({}, this.prototype.attributes, protoProps.attributes) |
|
return Waterline.Collection.extend.call(this, protoProps, staticProps) |
|
}; |
|
|
|
|
|
|
|
// Create the waterline instance. |
|
var waterline = new Waterline(); |
|
|
|
// Create a specification for a User model. |
|
var userCollection = BaseModel.extend({ |
|
identity: 'user', |
|
connection: 'default', |
|
attributes: { |
|
firstName: 'string', |
|
lastName: 'string', |
|
|
|
// Add a reference to Pets |
|
pets: { |
|
collection: 'pet', |
|
via: 'owner' |
|
} |
|
}, |
|
afterCreate: function(record, next){ |
|
console.log('User collection after create'); |
|
// petCollection.__super__.afterCreate(record, next); |
|
next(); |
|
}, |
|
afterUpdate: function(record, next){ |
|
console.log('User collection afterUpdate'); |
|
// petCollection.__super__.afterUpdate(record, next); |
|
next(); |
|
} |
|
}); |
|
|
|
// Create a specification for a Pet model. |
|
var petCollection = BaseModel.extend({ |
|
identity: 'pet', |
|
connection: 'default', |
|
attributes: { |
|
breed: 'string', |
|
type: 'string', |
|
name: 'string', |
|
|
|
// Add a reference to User |
|
owner: { |
|
model: 'user' |
|
} |
|
}, |
|
afterCreate: function(record, next){ |
|
console.log('pet collection after create'); |
|
// petCollection.__super__.afterCreate(record, next); |
|
next(); |
|
}, |
|
afterUpdate: function(record, next){ |
|
console.log('pet collection afterUpdate'); |
|
next(); |
|
} |
|
}); |
|
|
|
// Add the models to the waterline instance. |
|
waterline.loadCollection(userCollection); |
|
waterline.loadCollection(petCollection); |
|
|
|
// Set up the storage configuration for waterline. |
|
var config = { |
|
adapters: { |
|
'memory': sailsMemoryAdapter |
|
}, |
|
|
|
connections: { |
|
default: { |
|
adapter: 'memory' |
|
} |
|
} |
|
}; |
|
|
|
// Initialise the waterline instance. |
|
waterline.initialize(config, function (err, ontology) { |
|
if (err) { |
|
return console.error(err); |
|
} |
|
|
|
// Tease out fully initialised models. |
|
var User = ontology.collections.user; |
|
var Pet = ontology.collections.pet; |
|
|
|
// First we create a user. |
|
User.create({ |
|
firstName: 'Neil', |
|
lastName: 'Armstrong' |
|
}) |
|
.then(function (user) { |
|
// Then we can create a pet for the user. |
|
// Note that waterline automatically adds the `id` primary key to the model. |
|
Pet.create({ |
|
breed: 'beagle', |
|
type: 'dog', |
|
name: 'Astro', |
|
owner: user.id |
|
}) |
|
.then(function (pet) { |
|
// Then we can associate the pet with the user. |
|
user.pets = [pet]; |
|
|
|
// And save the user. |
|
return user.save(); |
|
}) |
|
.then(function () { |
|
// And now we want to get the new user back, |
|
// and populate the pets the user might own. |
|
return User.find() |
|
.populate('pets'); |
|
}) |
|
.then(console.log) |
|
.catch(console.error); |
|
}); |
|
}); |