This plugin enables class table inheritance .
When setting up you tables the parent table should contain a String column that contains the "kind" of class it is. (i.e. employee, staff, manager, executive). This allows the plugin to return the proper instance type when querying the tables.
All other tables that inherit from employee should contain a foreign key to their direct super class that is the same name as the primary key of the parent table(employee). So, in the above example staff and manager both contain foreign keys to employee and executive contains a foreign key to manager and they are all named id.
To set up you models the base super class should contain the ClassTableInheritancePlugin
var Employee = (exports.Employee = patio.addModel("employee", { plugins : [patio.plugins.ClassTableInheritancePlugin], static:{ init:function () { this._super(arguments); this.configure({key : "kind"}); } } }));All sub classes should just inherit their super class
var Staff = (exports.Staff = patio.addModel("staff", Employee, { static:{ init:function () { this._super(arguments); this.manyToOne("manager", {key : "managerId", fetchType : this.fetchType.EAGER}); } } })); var Manager = (exports.Manager = patio.addModel("manager", Employee, { static:{ init:function () { this._super(arguments); this.oneToMany("staff", {key : "managerId", fetchType : this.fetchType.EAGER}); } } }));
Executive inherits from manager, and through inheritance will also receive the oneToMany relationship with staff
var Executive = (exports.Executive = patio.addModel("executive", Manager));
Working with models
comb.when( new Employee({name:"Bob"}).save(), new Staff({name:"Greg"}).save(), new Manager({name:"Jane"}).save(), new Executive({name:"Sue"}).save() ).chain(function(){ return Employee.all().chain(function(emps){ var bob = emps[0], greg = emps[1], jane = emps[2], sue = emps[3]; console.log(bob instanceof Employee); //true console.log(greg instanceof Employee); //true console.log(greg instanceof Staff); //true console.log(jane instanceof Employee); //true console.log(jane instanceof Manager); //true console.log(sue instanceof Employee); //true console.log(sue instanceof Manager); //true console.log(sue instanceof Executive); //true }); });
Configures the plugins with the provided options. Note: This should only be called in the initial parent class.
ArgumentsAdditional options to configure behavior of the plugin
"key"
] String
: the column in the base table that contains the name of the subclass.
Funciton
: A callback to invoke on on the key returned from the database. This is useful if you are working with other orms that save the keys differently.
function (opts){ this.__configureOpts = opts; return this; }
Not typically called by user code. Sets up subclass inheritance.
Argumentsmodel that this class is inheriting from.
function (model){ this._super(arguments); var ctiKey = this.__ctiKey = model.__ctiKey; this.__ctiTables = model.__ctiTables.slice(); this.__ctiModels = model.__ctiModels.slice(); this.__ctiModels.push(this); this.__ctiTables.push(this.tableName); this.__ctiColumns = comb.merge({}, model.__ctiColumns); this.__ctiColumns[this.tableName] = this.columns; this.__ctiBaseModel = model.__ctiBaseModel; //copy over our schema var newSchema = comb.merge({}, this.__schema); var schemas = model.__ctiModels.map( function (m) { return m.schema; }).reverse(); schemas.forEach(function (s) { for (var i in s) { newSchema[i] = s[i]; } }, this); this._setSchema(newSchema); this._setDataset(model.dataset.join(this.tableName, this.primaryKey)); this._setPrimaryKey(this.__ctiBaseModel.primaryKey); this.pre("save", function (next) { if (ctiKey) { this[ctiKey] = this.tableName.toString(); } next(); }); }