I am trying to get the NODE-ORM2 extends to work. I am unable to find an all inclusive example to follow, only some partial that start at the model definition level (without reference to the DB).
Essentially I have two models A and B where there is a one to one relationship between them where B.AId is the foreign key to A.id (i probably should have established that in the db statements for simplicity, but orm2 doesn't read these relationships.
I don't understand why it is looking for an a_b relationship table. Nor do I understand how to form the relationship between the two Models.
Can anybody help? in the hasOne relationship we get to specify the fields - that seems to be missing here.
DB:
create table A
(
`id` int(11) NOT NULL AUTO_INCREMENT key,
`addedOn` date DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1718087 DEFAULT CHARSET=utf8;
create table B
(
`id` int(11) NOT NULL AUTO_INCREMENT KEY,
AId int(11),
`addedOn` date DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1718087 DEFAULT CHARSET=utf8;
insert into A (addedOn)values('2012-02-02')
insert into B (AId, addedOn)values((select id from A), '2012-02-04')
Models:
// User Model
module.exports = function (db, cb) {
console.log('ORM loading \'A\' model')
var A = db.define('A', {
id : Number,
addedOn : Date
}) ;
var B = A.extendsTo('B', {
id : Number,
AId : Number,
addedOn : Date
})
return cb()
}
Retrieval:
var A = req.db.models.A
A.get(1718087, {autoFetch: true}, function(err, a){
a.getB(function(err, b){
console.log(JSON.stringify(b, null, 4))
})
console.log(JSON.stringify(a, null, 4))
})
Exception:
ER_NO_SUCH_TABLE: Table 'mydb.a_b' doesn't exist
I was able to overcome the problem by specifying the table name and the foreign key inside of the Model definition:
var A = db.define('A', {
id : Number,
addedOn : Date
}) ;
var B = A.extendsTo('B', {
id : Number,
AId : Number,
addedOn : Date
}, {field: 'AId', table: 'B'})
Let's look inside of Extend.js for some of the reasoning:
exports.prepare = function (db, Model, associations, association_properties, model_fields) {
Model.extendsTo = function (name, properties, opts) {
opts = opts || {};
var assocName = opts.name || ucfirst(name);
var association = {
name : name,
table : opts.table || (Model.table + '_' + name),
field : util.wrapFieldObject(opts.field, Model, Model.table, Model.properties) || util.formatField(Model, Model.table, false, false),
getAccessor : opts.getAccessor || ("get" + assocName),
setAccessor : opts.setAccessor || ("set" + assocName),
hasAccessor : opts.hasAccessor || ("has" + assocName),
delAccessor : opts.delAccessor || ("remove" + assocName)
};
And then util.formatField:
association_key : "{name}_{field}",
So unless specified it assumes the table is the primary table concatenated to the model name. And the foreign key is primary_table concatenated with the field parameter.
In my case, without specifying the table and field, the node-orm code was looking fora table A_B with a foreign key A_id.