2

我想对多棵树中的对象进行分类以反映它们的特征并在其上建立导航。

因此,给定以下树:

Category1
-Category-1-1
-Category-1-2

Category2
-Category-2-1
-Category-2-2
--Category-2-2-1

一个对象可以例如属于Category-1-2 和Category-2-2-1。

目标是能够从数据库中获取所有对象

  • 属于某个类别的
  • 属于某个类别或其后代的

一个更实际的例子:

一个类别可能具有“工具 > 园艺工具 > 刀具”的层次结构。

第二类:“硬物 > 金属物 > 小金属物”

对象“Pruners”将被归类为“Cutters”以及“Small metal objects”。

我希望能够

  • 检索所有“园艺工具”->“修枝剪”
  • 检索“园艺工具”->“刀具”的所有类别子项
  • 检索所有“硬对象”->“修剪器”
  • 检索所有也是“切割器”->“修枝器”的“硬物”
  • 检索所有也是“刀具”的“软对象”-> [] 任何指针?我已经简要地查看了closure_tree、awesome_nested_sets 等,但我不确定它们是否合适。
4

3 回答 3

5

请注意,这里的代码都是伪代码。

我将使用祖先gem,并使用三个模型类对您的数据进行建模。这样你的数据就被标准化了,这是一个很好的基础。

Category - ancestry tree
  has_may Memberships
  has_may Products through Memberships

Membership
  belongs_to Category
  belongs_to Products

Products
  has_may Memberships
  has_may Categories through Memberships

从那里开始,您需要弄清楚如何有效地执行查询。我这样做的方法是了解如何使用 SQL 来完成,然后弄清楚如何使用 activercord 的 DSL 来表达查询。

一些资源:

查询示例:

找到一个类别。

Category.find(category_id)

找到一个类别并将其产品包含在指定的类别中。

Category.find(category_id).join(:memberships => :products)

查找类别的子树 ind 包括产品

Category.subtree_of(category_id).join(:memberships => :products)

查找产品所属的所有类别。

Product.find(product_id).categories

于 2013-03-11T13:49:43.670 回答
4

我只是这样做了,我选择不使用祖先,而是使用closure_tree,因为作者说它更快,我同意他的观点。知道您需要在类别(每当我将多个添加到单个对象时,我喜欢调用标签)和对象之间有一个“has_and_belongs_to_many”。

现在发现者,坏消息是,如果没有您自己的自定义查询,您可能无法使用它来完成。使用 gems 方法,您将执行以下操作:

Item.joins(:tags).where(tags: {id: self_and_descendant_ids })

代码是干净的,它执行两个查询,一个用于descendant_ids,另一个用于Objects。这一点的细微变化,应该给你除了最后一个之外你所需要的一切。那个很难,我还没有实施(我正在处理中)。

现在,您必须同时调用tag.self_and_ancestor_ids(查询计数:2)、这些标签中的所有项目(查询计数:4)和相交。在此之后,需要进行一些认真的重构。我认为我们需要编写 SQL 来减少查询次数,我认为 Rails 查询接口还不够。

我选择 *closure_tree* 的另一个原因是使用 parent_id,所有兄弟姐妹共享它(就像任何其他 Rails 关联一样),因此它更容易与其他 gem 交互(例如 RankedModel 排序)。

于 2013-03-12T03:09:58.823 回答
2

我认为您可以选择其中一颗树宝石,我个人喜欢Ancestry。然后为每个类别建立一个关联有许多对象,每个对象可以属于许多类别。

您是否已经偶然发现任何问题,或者您只是在研究您的选择?

于 2013-03-08T12:54:18.010 回答