balderdashy / sails

Realtime MVC Framework for Node.js
https://sailsjs.com
MIT License
22.84k stars 1.95k forks source link

Associations with custom Primary Keys don't populate the PK after .create() #5994

Closed appdevdesigns closed 5 years ago

appdevdesigns commented 10 years ago

I've defined the following 2 models in a 1-Many fashion:

Person.js
module.exports = {
    tableName:"old_person_data",
    autoCreatedAt:false,
    autoUpdatedAt:false,
    autoPK:false,
//    migrate:'safe',

    connection: ['legacy_db'],
    config:{
        pool:false
    },

    attributes: {
        ren_id  : { 
            type:'INTEGER',
            primaryKey:true
        },
        ren_guid    : 'STRING',
        ren_surname : 'STRING',
        ren_givenname   : 'STRING',
        phones:{
            collection: 'Phone',
            via: 'ren_id'
        }
    }
};

and

Phone.js
module.exports = {
    tableName:"old_phone_data",
    autoCreatedAt:false,
    autoUpdatedAt:false,
    autoPK:false,
//    migrate:'safe',

    connection: ['legacy_db'],
    config:{
        pool:false
    },

    attributes: {
        phone_id    : { 
            type:'INTEGER',
            primaryKey:true
        },
        phone_guid  : 'STRING',
        ren_id  : { 
            model:'Person'
        },
        phonetype_id    : 'INTEGER',
        phone_countrycode   : 'INTEGER',
        phone_number    : 'STRING'
    }
};

Now I'm trying to populate the two models using the following routine:

var processIt = function(personDef, phoneDef, next) {

    Person.create(personDef).exec(function(err, personObj){
        if (err) {
            next(err);
        } else {
Log('personObj:', personObj);

            if (phoneDef) {
                personObj.phones.add(phoneDef);
                personObj.save(function(err){
if (err) Log('err:', err);
                    next(err);
                });

            } else {
                next();
            }
        }
    });
}

When I run this adding data to the function(), I get the following output:

 personObj:{
    "ren_guid": "BE451869-EF9A-9C05-71A2-F9E7BFC4CF26",
    "ren_surname": "Spencer",
    "ren_givenname": "Kenyon"
}
 err:{}

Notice that there is no, ren_id returned on the personObj from the create().exec() methods.

however, if I change the routine to immediately lookup the person from the create() routine like this:

var processIt = function(personDef, phoneDef, next) {

    Person.create(personDef).exec(function(err, personObj){

Person.findOne({ren_guid:personObj.ren_guid}).exec(function(err, personObj){ 
        if (err) {
            next(err);
        } else {
Log('personObj:', personObj);

            if (phoneDef) {
                personObj.phones.add(phoneDef);
                personObj.save(function(err){
if (err) Log('err:', err);
                    next(err);
                });

            } else {
                next();
            }
        }
}); // end findOne()
    });
}

I now get the following output:

personObj:{
    "ren_id": 1,
    "ren_guid": "BE451869-EF9A-9C05-71A2-F9E7BFC4CF26",
    "ren_surname": "Spencer",
    "ren_givenname": "Kenyon"
}
personObj:{
    "ren_id": 2,
    "ren_guid": "BAB632A3-0C02-DB7E-2B5F-01FEC1362B02",
    "ren_surname": "Slater",
    "ren_givenname": "Julian"
}
...
[all remaining data is updated]
...

And everything works as expected.

It seems that on the .create() method, the custom primary key isn't being set, and the resulting modelInstance isn't able to properly .save() it's data.

Is this the expected behavior?

randallmeeker commented 10 years ago

does this help? https://github.com/balderdashy/waterline/issues/481

appdevdesigns commented 10 years ago

Brilliant!

Adding autoIncrement:true to the primary key definition now returns the value to the instance returned from .create(). And everything works fine.

I guess it makes sense if I think about it. But I agree with you, there needs to be some more documentation on how to migrate existing tables into sails. Or at least a 'things to watch out for' section on the documentation page.

Thanks for answering this one!