sequelize-nested-sets v1.1.0
Nested Sets Behavior for Sequelize
Behavior for storing and managing nested sets
Installation
npm install --save sequelize-nested-setsConfiguring
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 MenuPrepending 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 PageAppending 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 PageInserting 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 PageInserting 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 PageGetting 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' } });