父子树形结构gem "ancestry" 的安装使用

flchp 关注2023-08-08112312322


父子树形结构是一个比较常见的结构,比如:电商平台商品的多级分类(一级分类,二级分类,三级分类),公司的多级组织(集团公司、省公司、市公司、县公司)等。

针对这种结构的设计,ruby中有非常好用gem: "ancestry" ,下面介绍一下这个gem的基本用法。

安装

Gemfile
1
+ gem 'ancestry'

($代表在命令行执行)

执行$ bundle install,重启rails s

给需要父子树形结构的model如:category添加ancestry字段。

执行$ rails g migration add_ancestry_to_categories ancestry:string:index;执行:$ rake db:migrate

app/models/category.rb
1
+ has_ancestry

gem基本用法

创建子节点:
@category.children.create

查询子节点:
@category.children

查询自己及以下的所有节点:
@category.subtree

查询父节点:
@category.parent

查询当前节点的层级(顶级节点为0,其子类为1,依此类推):
@category.depth

查询某个层级的所有节点比如第二层的所有节点:
Category.at_depth(1)
其他scope方法:
before_depth(depth) Return nodes that are less deep than depth (node.depth < depth)
to_depth(depth) Return nodes up to a certain depth (node.depth <= depth)
at_depth(depth) Return nodes that are at depth (node.depth == depth)
from_depth(depth) Return nodes starting from a certain depth (node.depth >= depth)
after_depth(depth) Return nodes that are deeper than depth (node.depth > depth)

添加字段存储层级和子节点数量

执行$ rails g migration add_ancestry_depth_and_children_count_to_categories ancestry_depth:integer:default[0] children_count:integer,生产迁移文件后执行$ rake db:migrate

app/models/category.rb
1
2
- has_ancestry
+ has_ancestry cache_depth: true, touch: true, counter_cache: true

执行$ rails c,进入程序控制台执行Category.rebuild_depth_cache!

注意:要使用会触发回调的增删改查方法,才会正确维护counter_cache的值。

delete、decrement等方法不会处罚回调,不会更新counter_cache的值。

常见场景用法

一个常见场景:分类下有多中商品

app/models/category.rb
1
2
3
4
5
class Category < ApplicationRecord
  has_ancestry

  +has_many :products
end

查询当前分类节点:
@category = Category.find(params[:id])

查询当前分类节点下所有商品:
@products = @category.products

查询当前分类的子级分类下所有商品:
@subcategories = @category.children
@products = @subcategories.map(&:products).flatten

查询当前分类节点和子孙分类节点下的所有商品:
@categories = @category.subtree
@products = @categories.map(&:products).flatten


上一篇 返回目录 下一篇