Gem Awesome nested set cài đặt mô hình nested set model trong Rails
This post hasn't been updated for 3 years
Giới thiệu
Bài viết này em giới thiệu việc áp dụng gem awesome nested set
để cài đặt mô hình cây phân cấp trong model trong ứng dụng Rails.
Mọi người có thể xem lại bài giới thiệu cách hoạt động của nested set model
tại đây:
https://viblo.asia/bui.thi.phan/posts/EoDkQqKPkbV
Gem Awesome nested set
cung cấp các phương thức hữu ích thuận lợi cho việc sử dụng và truy vấn đối với model cài đặt mô hình trên.
Ngoài ra, gemAwesome nested set
cũng hỗ trợ việc cài đặt mô hình parent-child
trong cây phân cấp.
Cài đặt
Thêm vào Gemfile:
gem 'awesome_nested_set'
sau đó chaỵ bundle install
để cài đặt gem này.
Sử dụng
Để sử dụng awesome_nested_set
, ta cần thêm 3 trường sau vào trong model: parent_id
, lft
, rgt
. 3 trường này là bắt buộc phải có trong model. parent_id
lưu giá trị của id của node cha, lft
và rgt
lưu các giá trị left và right của mỗi node và chúng sẽ tự được cập nhập khi tạo node mới, xóa node hay thay đổi 1 node.
Khi sử dụng, ta sẽ chỉ cần create, update các node với các trường có sẵn và parent_id
, còn lft
và rgt
sẽ được cập nhập tự động.
Ngoài những trường trên, ta cũng có thể thêm các trường khác như: depth
và children_count
. Các trường này cũng được tự động cập nhập giá trị trong đó, children_count
phải khác nil
và có giá trị default: 0
.
Để sử dụng các phương thức hỗ trợ của gem này, ta thêm dòng sau vào trong model:
Như vậy, model của ta đã có thể sử dụng được cách cài đặt nested set model
rồi.
Một số phương thức hữu ích hay sử dụng:
- Class method:
Category.root #lấy node root đầu tiên
Category.roots #lấy tất cả các node root
- Instance methods
category.root #lấy ra node root của category
category.parent #lấy ra node cha của category
category.children #lấy các node con của category (chỉ lấy các node có level nhỏ hơn category 1 đơn vị)
category.ancestors #lấy ra mảng gồm node cha, cha của node cha... cho tới node root.
category.self_and_ancestors #lấy ra các node cha, cha của node cha... cho tới root và bao gồm cả category.
category.siblings #lấy ra các anh chị em cùng level của category
category.self_and_siblings #lấy ra tất cả các anh chị em cùng level với category và bao gồm cả category
category.descendants #lấy ra tất cả các node con, node con của node con...
category.self_and_descendants#lấy tất cả các node con, node con của node con và bao gồm cả node category
category.leaves #lâý ra tất cả các node con, node con của node con là node lá.
category.root? #true nếu cateogry là node root
category.child? #true nếu category là node con
category.is_ancestor_of(obj) #true nếu obj là node cha ông của category
category.is_or_is_ancestor_of(obj) #true nếu obj là node cha ông của category hoặc category là obj
category.is_descendant_of(obj) #true nếu obj là node con cháu của category
category.is_or_is_descendant_of(obj) #true nếu obj là node con cháu của category hoặc obj chính là node category
category.leaf? #true nếu category là node lá
Ta có thể sử dụng nested_set_options
để tạo form select trên view thay vì phải định nghĩa ra collection phức tạp bằng đệ quy.
<%= f.select :parent_id, nested_set_options( Category, category) {|i| "#{'-' * i.level} #{i.name}" } %>
<%= select_tag 'parent_id', options_for_select(nested_set_options(Category) {|i| "#{'-' * i.level} #{i.name}" } ) %>
Tổng kết
Với gem awesome nested set, ta có thể giảm lược đi rất nhiều các thao tác xử lý logic phức tạp trong việc sử dụng mô hình nested set model
trong ứng dụng của mình.
Mong rằng bài viết có thể giúp ích cho mọi người.
Link tham khảo:
All Rights Reserved