Shamoon
Shamoon

Reputation: 43639

How do I set a foreign key for a Sequelize model?

This is very basic, and should work.. but doesn't. So first my models:

const Conversation = sequelize.define('Conversation', {
        name: {
            type: DataTypes.STRING,
            allowNull: false
        },
        ...
})
Conversation.associate = (models, options) => {
    Conversation.hasOne(models.Audio, options)
}

and:

module.exports = (sequelize /*: sequelize */ , DataTypes /*: DataTypes */ ) => {
    const Audio = sequelize.define("Audio", {
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: true
        },
    })

    Audio.associate = (models, options) => {
        Audio.belongsTo(models.Conversation, options)
    }

I have a model loader that does:

    fs.readdirSync(`${__dirname}`)
        .filter((modelFile) => {
            return path.extname(modelFile) === '.js' && modelFile !== 'index.js'
        })
        .map((modelFile) => {
            let model = sequelize.import(`./${modelFile}`)
            models[model.name] = model

            return model
        })
        .filter((model) => models[model.name].associate)
        .forEach((model) => {
            models[model.name].associate(models, {
                hooks: true,
                onDelete: 'CASCADE'
            });
        })

So it calls the associate method for all models that have it defined. This works, in that, when I .sync it, it creates a ConversationId field in my Conversations table.

When I try to execute:

            let updAudio = {
                ConversationId,
                name: 'myname'
            }
            await global.db.models.Audio.create(updAudio, { logging: console.log })

ConversationId is not null, but when it saves in the DB, it's null. I've inspected it a hundred times. The raw query looks like:

INSERT INTO "Audios" ("id","name","createdAt","updatedAt") VALUES (DEFAULT,'myname','2019-10-20 19:59:18.139 +00:00','2019-10-20 19:59:18.139 +00:00') RETURNING *;

So what happened to ConversationId?

Upvotes: 6

Views: 12050

Answers (1)

Alex Pappas
Alex Pappas

Reputation: 2677

You might need to add the foreign key in the model definition:

(One of the two may work)

 const Audio = sequelize.define("Audio", {
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: true
        },
        conversationId : {
            type: Sequelize.INTEGER,
            references: 'Conversations' // or "conversations"? This is a table name
            referencesKey: 'id' // the PK column name
        }
    })

or

 const Audio = sequelize.define("Audio", {
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: true
        },
        conversationId : {
            type: Sequelize.INTEGER,
            references: {
                model: Conversation
                key: 'id'
            }
        }
    })

You might also need to define your belongsTo association this way:

Audio.belongsTo(Conversation, foreignKey: 'conversationId');

Try to look for the generated raw query on creation of the tables and start from there.

Upvotes: 10

Related Questions