node.jssequelize.jssequelize-typescript

Create one to many relationship object in database using Sequelize


I've searched a lot and didn't find any answer. My english isn't that good so i might not used the best keywords...

Here is my problem, is there a way to insert in one query an object like this ?

I have a one to many relationship between two objects define like this :

foo can have many bar

bar can have one foo

export const foo = sequelize.define('foos', {
    idfoo: {
        type: Sequelize.INTEGER,
        autoIncrement: true,
        primaryKey: true
    },
    value: Sequelize.STRING,
    valueInt: Sequelize.INTEGER
})

export const bar = sequelize.define('bars', {
idbar: {
    type: Sequelize.INTEGER,
    autoIncrement: true,
    primaryKey: true
},
    value: Sequelize.STRING,
    valueInt: Sequelize.INTEGER
})

foo.hasMany(bar, {
    foreignKey: 'idfoo'
});
bar.belongsTo(foo);

Imagine you got this object you want to insert in your db. How would you do it ?

{
    "value": "test",
    "valueInt": 5,
    "bars": [
        {
            "value": "test",
            "valueInt": 6
        },
        {
            "value": "test",
            "valueInt": 7
        }
    ]
}

I have read Sequelize documentation i didn't find any clue of this issue (or maybe i've missed it ).

I wasn't be able to make this solution works Sequelize : One-to-Many relationship not working when inserting values

Actually here is my Sequelize create function, i thought Sequelize handled all the imports alone (pretty naive i guess)...

static async post(body) {
    await foo.create(body);
}

Solution

  • First, you need to indicate the same foreignKey option for both paired associations:

    foo.hasMany(bar, {
        foreignKey: 'idfoo'
    });
    bar.belongsTo(foo, {
        foreignKey: 'idfoo'
    });
    

    That way Sequelize can make sure these two models linked by the same fields from both ends.
    Second, in order to insert both main and child records together you need to indicate the include option in the create call with bar model:

    static async post(body) {
        await foo.create(body, {
         include: [bar]
        });
    }