sequelize-nested-sets v1.1.0
Nested Sets Behavior for Sequelize
Behavior for storing and managing nested sets
Installation
npm install --save sequelize-nested-sets
Configuring
The library works as a wrapper over the model before initialization.
Configure model:
// yourModel.js
const { Model } = require('sequelize');
const ns = require('sequelize-nested-sets');
// with class extending Model
module.exports = (sequelize, DataTypes) => {
class Menu extends Model {
// additional methods, associations
}
return ns(sequelize, 'menu', {
name: DataTypes.STRING,
}, {
tableName: 'menu',
treeAttribute: 'tree',
},
Menu
);
};
// or without ES6 classes
module.exports = (sequelize, DataTypes) => {
const Menu = ns(sequelize, 'menu', {
name: DataTypes.STRING,
}, {
tableName: 'menu',
treeAttribute: 'tree',
}
);
return Menu;
};
DB Table Structure:
Your table must have follow columns:
- lft (int unsigned NOT NULL)
- rgt (int unsigned NOT NULL)
- depth (int unsigned NOT NULL)
- tree (int unsigned NOT NULL) (if you use multiple tree)
You can specify custom column names in options
Nested Sets Options
ns(sequelize, modelName, attributes, [options], [Model])
To use multiple tree mode set treeAttribute.
Adds nested set behavior using the model wrapper
Param | Type | Default | Description |
---|---|---|---|
sequelize | sequelize | Ready sequelize object with connection | |
modelName | string | Model name | |
attributes | object | Model attributes | |
options | object | {} | Sequelize and Nested sets options |
options.treeAttribute | string | false | Column name for tree id, specify for use multiple tree |
options.leftAttribute | string | "lft" | Column name for left attribute |
options.rightAttribute | string | "rgt" | Column name for right attribute |
options.depthAttribute | string | "depth" | Column name for depth attribute |
Model | Model | Extended Model class |
Usage
Moving, Creating node
Making a root node
To make a root node
const menu = Menu.build({ name: 'Main Menu' });
await menu.makeRoot();
The tree will look like this
— Main Menu
Prepending a node as the first child of another node
To prepend a node as the first child of another node
const productPage = Menu.build({ name: 'Product Page' });
await productPage.prependTo(menu);
The tree will look like this
— Main Menu
— — Product Page
Appending a node as the last child of another node
To prepend a node as the last child of another node
const faqPage= Menu.build({ name: 'FAQ Page' });
await faqPage.appendTo(menu);
The tree will look like this
— Main Menu
— — Product Page
— — FAQ Page
Inserting a node before another node
To insert a node before another node
const homePage = Menu.build({ name: 'Home Page' });
await homePage.insertBefore(productPage);
The tree will look like this
— Main Menu
— — Home Page
— — Product Page
— — FAQ Page
Inserting a node after another node
To insert a node after another node
const contactPage = Menu.build({ name: 'Contact Page' });
await contactPage.insertBefore(faqPage);
The tree will look like this
— Main Menu
— — Home Page
— — Product Page
— — FAQ Page
— — Contact Page
Getting nodes
Getting the root nodes
To get all the root nodes
const roots = await Menu.roots();
Getting the leaves nodes
To get all the leaves nodes
const leaves = await Menu.leaves();
To get all the leaves of a node
const menu = await Menu.findOne({ where: { name: 'Main Menu' } });
const leaves = await menu.leave();
Getting children of a node
model.children([depth = null], [options = {}]);
To get all the children of a node
const menu = await Menu.findOne({ where: { name: 'Main Menu' } });
const children = await menu.children();
To get the first level children of a node
const menu = await Menu.findOne({ where: { name: 'Main Menu' } });
const children = await menu.children(1);
To get the children by condition
const menu = await Menu.findOne({ where: { name: 'Main Menu' } });
const children = await menu.children(null, { where: { name: 'FAQ Page' } });
Getting parents of a node
model.parents([depth = null], [options = {}]);
To get all the parents of a node
const faqPage = await Menu.findOne({ where: { name: 'FAQ Page' } });
const parents = await faqPage.parents();
To get the first parent of a node
const faqPage = await Menu.findOne({ where: { name: 'FAQ Page' } });
const parents = await faqPage.parents(1);
To get the parent by condition
const faqPage = await Menu.findOne({ where: { name: 'FAQ Page' } });
const parents = await menu.parents(null, { where: { name: 'Main Menu' } });