具有 rails gem 祖先的嵌套类别。

具有 rails gem 祖先的嵌套类别。

原文:https://medium.com/hackernoon/nested-categories-with-rails-gem-ancestry-112ca8bbbf98

想象一下你正在处理项目其中你有类别,以及这些类别中的产品,以服装网站为例。您可能有以下类别树:

Women
  - Bags
  - Clothes
    - Shirts
    - Jeans [SELECTED]
      - Straight
      - Skinny
  ...
Men
  - Accessories
  - Shoes
  ...

数据库结构非常简单——id、parent_id、类别标题和产品类别 id。非常简单,您可以很容易地获得某个类别的父类和/或子类。

但是你需要考虑——如果你选择了牛仔裤,就意味着你想要牛仔裤+直筒牛仔裤+紧身牛仔裤等等。要实现这一点,您需要选定的类别 id 及其子类别 id。用 rails 很容易得到它们,只需为它编写一个小的自定义范围。

但是如果孩子有自己的孩子,树深得多呢?您将不得不编写高级查询、连接、递归来获取所有级别上的子 id。或者假设您已经选择了最后一个类别,并且您想要获取它的所有现有父类别,或者您想要所选类别的兄弟类别(所选级别上的所有项目,如衬衫、牛仔裤等)。通过为所有这样的情况编写定制的范围和方法,您将很快得到一个庞大而混乱的模型。

处理嵌套类别的最好工具之一是 gem Ancestry(https://github.com/stefankroes/ancestry),它有很多助手作用域和方法,特别是对于上面提到的情况。

用途

祖先非常容易理解和使用。

此处举例项目:https://github.com/gioch/ancestry_test.git

  • 将 gem ancestry添加到 Gemfile。
  • 为类别创建模型(没有 parent_id 或类似东西,ancestry 会为我们处理它)
  • 生成迁移以将祖先字段添加到类别:
rails g migration add_ancestry_to_category ancestry:string:index### it will add new column to categories, which will handle parent/child stuff
  • 将“has_ancestry”添加到类别模型
class Category < ApplicationRecord
  has_ancestry
end

创建类别和子类别

创建子类别很容易,你只需要在创建时指定parent:

women = Category.create(name: 'Women')
women_bags = Category.create(name: 'Bags', parent: women)
women_clothes = Category.create(name: 'Clothes', parent: women)# Check seeds.rb inside example project for more seeds.

获取所选类别的所有子类别

祖先的助手们正在像魔法一样工作。使用方法children获得子类别,或者使用child_ids只获得子类别的 id 数组:

# category {Women}
cat = Category.first# [{Bags}, {Clothes}]
child_objects = cat.children# [2, 3]
child_ids = cat.child_ids

但是,如上所述,如果树非常深,并且您想要所有级别的子节点,请使用descendants来代替:

# [{Bags}, {Clothes}, {Shirts}, {Jeans}, {Straight}, {Skinny}]
all_children = cat.descendants# [2, 3, 4, 5, 6, 7]
all_child_ids = cat.descendant_ids

获取所选类别的所有父类别

如果您选择了树中的最后一个类别,并且您想要获得所有父类别,请使用ancestorsancestor_ids:

# get category {Straight}
cat = Category.find(7)# get parent category objects [{Women}, {Clothes}, {Jeans}]
all_parents = cat.ancestors# get parent category ids [1, 3, 5]
all_parent_ids = cat.ancestor_ids

获取指定类别的产品

# get category {Clothes}
cat = Category.find(3)# get child ids
descendant_ids = cat.descendant_ids# include selected category id if needed
descendant_ids << cat.idProduct.where(category_id: descendant_ids)

祖先还有很多其他有用的方法。

额外资源

点击这里查看祖先的 github 页面-【https://github.com/stefankroes/ancestry

查查 Railscast 的血统—【http://railscasts.com/episodes/262-trees-with-ancestry


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除