12/08/2018, 14:09

Gem Awesome nested set cài đặt mô hình nested set model trong Rails

Giới thiệu Lần trước em đã giới thiệu về cách hoạt động của nested set model trong mô hình cây phân cấp, bài viết này em sẽ giới thiệu việc áp dụng gem awesome nested set để cài đặt mô hình này 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 ...

Giới thiệu

Lần trước em đã giới thiệu về cách hoạt động của nested set model trong mô hình cây phân cấp, bài viết này em sẽ giới thiệu việc áp dụng gem awesome nested set để cài đặt mô hình này 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.

categorymodel.png

Để 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:

category-model.png

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:

https://github.com/collectiveidea/awesome_nested_set

0