Nested Set is an Go implementation of the Nested set model for Gorm.
Nested Set is an implementation of the Nested set model for Gorm.
This project is the Go version of awesome_nested_set, which uses the same data structure design, so it uses the same data together with awesome_nested_set.
Actually the original design is for this, the content managed by awesome_nested_set in our Rails application, the front-end Go API also needs to be maintained.
This is a Go version of the awesome_nested_set, and it built for compatible with awesome_nested_set.
For manage a nested tree node like this:
Video taken from BlueDoc, used by awesome_nested_set + react-dnd.
go get github.com/longbridgeapp/nested-set
You must use nestedset
Stuct tag to define your Gorm model like this:
Support struct tags:
id
- int64 - Primary key of the nodeparent_id
- sql.NullInt64 - ParentID column, null is rootlft
- intrgt
- intdepth
- int - Depth of the nodechildren_count
- Number of childrenOptional:
scope
- restricts what is to be considered a list. You can also setup scope by multiple attributes.Example:
import (
"database/sql"
"github.com/longbridgeapp/nested-set"
)
// Category
type Category struct {
ID int64 `gorm:"PRIMARY_KEY;AUTO_INCREMENT" nestedset:"id"`
ParentID sql.NullInt64 `nestedset:"parent_id"`
UserType string `nestedset:"scope"`
UserID int64 `nestedset:"scope"`
Rgt int `nestedset:"rgt"`
Lft int `nestedset:"lft"`
Depth int `nestedset:"depth"`
ChildrenCount int `nestedset:"children_count"`
Title string
}
import nestedset "github.com/longbridgeapp/nested-set"
// create a new node root level last child
nestedset.Create(tx, &node, nil)
// create a new node as parent first child
nestedset.Create(tx, &node, &parent)
// nestedset.MoveDirectionLeft
// nestedset.MoveDirectionRight
// nestedset.MoveDirectionInner
nestedset.MoveTo(tx, node, to, nestedset.MoveDirectionLeft)
// With scope, limit tree in a scope
tx := db.Model(&Category{}).Where("user_type = ? AND user_id = ?", "User", 100)
// Get all nodes
categories, _ := tx.Order("lft asc").Error
// Get root nodes
categories, _ := tx.Where("parent_id IS NULL").Order("lft asc").Error
// Get childrens
categories, _ := tx.Where("parent_id = ?", parentCategory.ID).Order("lft asc").Error
$ createdb nested-set-test
$ go test ./...
-- some useful sql to check status
SELECT n.id,
CONCAT(REPEAT('. . ', (COUNT(p.id) - 1)::int), n.title) AS t,
n.title, n.lft, n.rgt, n.depth, n.children_count
FROM categories AS n, categories AS p
WHERE (n.lft BETWEEN p.lft AND p.rgt)
GROUP BY n.id ORDER BY n.lft;
MIT