Q:

All nested rows does not inserted in a table

I want tree structure in my Categories table.
So I tried this:
Categories model looks like:
import * as Sequelize from 'sequelize';

export default class CategoriesModel extends Sequelize.Model {
    static init(sequelize, DataTypes) {
        return super.init({
            name: {
                type: DataTypes.STRING,
            },
        }, {
            modelName: 'categories',
            sequelize,
        });
    }
}

association in my CategoriesModel class looks like:

    static associate({ Categories }) {
        this.nestedCategories = this.hasMany(Categories, {
            as: 'nestedCategories',
            foreignKey: 'parentId',
        });
    }

and when i tried to insert rows, for example:
sequelize.sync({ force: true }).then(() => {
    models.Categories.create({
        name: 'parent',
        nestedCategories: [
            {
                name: 'child 1',
            }, 
            {
                name: 'child 2',
                nestedCategories: [
                    {
                        name: 'child 3',
                    }
                ],
            },
        ],
    }, {
        include: [models.Categories.nestedCategories]
    }).then(cat => {
        console.log(cat.toJSON());
    })
});

result is:
{ 
  id: 1,
  name: 'parent',
  nestedCategories:
   [ { id: 2,
       name: 'child 1',
       parentId: 1,
       updatedAt: 2019-02-05T08:39:45.655Z,
       createdAt: 2019-02-05T08:39:45.655Z },
     { id: 3,
       name: 'child 2',
       parentId: 1,
       updatedAt: 2019-02-05T08:39:45.657Z,
       createdAt: 2019-02-05T08:39:45.657Z } ],
  updatedAt: 2019-02-05T08:39:45.624Z,
  createdAt: 2019-02-05T08:39:45.624Z,
  parentId: null 
}

child 3 does not inserted in a table.
I dont understand what i'm doing wrong...

A:

You need to specify one include per nested category in order to make your request parsed correctly.
Here I made a function to do this recursively based on model you want to create:
function buildIncludeRecursive(model, includeTemplate) {
    const include = Object.assign({}, includeTemplate);
    let currInclude = include;
    let currModel = model;
    while(currModel[includeTemplate.as]){
        currInclude.include = [Object.assign({}, includeTemplate)];
        currInclude = currInclude.includes[0];
        currModel = currModel[includeTemplate.as];
    }
    return include;
}

const model = {
     name: 'parent',
     nestedCategories: [
         { name: 'child 1' }, 
         {
             name: 'child 2',
             nestedCategories: [
                { name: 'child 3' }
             ]
        },
    ],
};

const includeTemplate = {
    model: models.Categories,
    as: 'nestedCategories'
};

model.categories.create(model, { 
    include: buildIncludeRecursive(model, includeTemplate)
});

Here's what your include is gonna be in this case:
{
    model: models.Categories,
    as: 'nestedCategories',
    include: [
        {
            model: models.Categories,
            as: 'nestedCategories'
        }
    ]
}

