balderdashy / sails

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

Assosiattions wrong types (one-to-many) #5294

Closed bonanzakrak closed 5 years ago

bonanzakrak commented 8 years ago

Waterline version: 0.11.2 Node version: v4.4.2 NPM version: 2.15.0 Operating system: Mac OSX


As adapter i use sails-mongo (0.11.7). In some Models i want _id to be integer for some reason. Here are 2 Models.

User.js

module.exports = {
    tableName: 'users',
    schema: true,
    attributes: {
        USERNAME: {
            type: 'string',
            alphanumericdashed: true
        },
        pokesSent: {
            collection: 'Poke',
            via: 'SENDER'
        },
        pokes: {
            collection: 'Poke',
            via: 'USER'
        },
        _id: {
            type: 'integer'
        }
    }
}

Poke.js

module.exports = {
    tableName: 'pokes',
    schema: true,

    attributes: {
        SENDER: {
            model: 'User'
        },
        USER: {
            model: 'User'
        },
        SEND_DATE: {
            type: 'datetime',
            defaultsTo: function() {
                return new Date();
            }
        }
    }
}

Issue: When i create document in Poke model it casts 'USER' & 'SENDER' to String. It doesn't get type from User model.

Model1.create({
    SENDER: 1,
    USER: 2
})

result:

{'SENDER':'1','USER':'2',SEND_DATE: ...}

and should be:

{'SENDER':1,'USER':2,SEND_DATE: ...}

There is a workaround. But it would be really nice if type could populate through foreign key.

Poke.js

module.exports = {
    tableName: 'pokes',
    schema: true,

    attributes: {
        SENDER: {
            model: 'User',
            **type: 'integer'**
        },
        USER: {
            model: 'User',
            **type: 'integer'**
        },
        SEND_DATE: {
            type: 'datetime',
            defaultsTo: function() {
                return new Date();
            }
        }
    }
}
particlebanana commented 8 years ago

The model keys are going to be looking for an id field. For Mongo, we automatically map id -> _id. Could you try setting your User.js model to the following:

module.exports = {
    tableName: 'users',
    schema: true,
    autoPK: false,
    attributes: {
        USERNAME: {
            type: 'string',
            alphanumericdashed: true
        },
        pokesSent: {
            collection: 'Poke',
            via: 'SENDER'
        },
        pokes: {
            collection: 'Poke',
            via: 'USER'
        },
        id: {
            type: 'integer'
        }
    }
}
bonanzakrak commented 8 years ago

You need to add primaryKey: true to id. If it's missing there is error raising

/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/foreignKeys.js:104 throw new Error(error); ^ Error: Trying to create an association on a model that doesn't have a Primary Key.

So the model need to looks like this. I understand that i need to set it as Primary Key manually, because i overwrite default settings for id?

module.exports = {
    tableName: 'users',
    schema: true,
    autoPK: false,
    attributes: {
        USERNAME: {
            type: 'string',
            alphanumericdashed: true
        },
        pokesSent: {
            collection: 'Poke',
            via: 'SENDER'
        },
        pokes: {
            collection: 'Poke',
            via: 'USER'
        },
        id: {
            type: 'integer',
            primaryKey: true
        }
    }
}