递归加载层次结构中的所有子/父记录

时间:2011-09-27 19:49:34

标签: mysql ruby-on-rails ruby hierarchy

- Rails:2.3.8,Ruby:1.9.2v180,MySQL:5.1.56 -

我有一个名为ExternalCategory的递归模型

  belongs_to :parent, :class_name => "ExternalCategory", :foreign_key => "parent_id"

  has_many :children, :class_name => "ExternalCategory", :foreign_key => "parent_id"

我在分页视图中显示此层次结构,其中最初只能看到一些顶级类别。这些顶级类别的所有祖先都会加载到页面中,但只能通过js显示。

一个ExternalCategory可能有超过1000个祖先,所以如果没有急切加载这些页面可能需要花费大量时间来加载。话虽这么说,我一直在努力以适当的方式添加急切的加载,但我不太清楚会是什么。也许你可以帮忙。

目前,我在ExternalCategory中有top_level_categories的范围:

named_scope :top_level_categories, :conditions => "parent_id is null"

然后在上面的has_many :children ...行结束时添加了这个警告:

   , :include => :children

所以现在每当我加载任何ExternalCategory的子元素时,这些子元素的子元素以及所有这些子元素的子元素都会被加载,依此类推。理想情况下,我不会在模型本身中这样做,而是在范围内,但是现在我可以用一点点的疯狂。

所有这些主要的问题是我在我的表中构建行id,它引用当前元素的id以及它的所有祖先的id。在展开/折叠任何类别的子视图时,js会使用此ID。为了创建这些ID,我通过递归调用#parent来访问当前类别的祖先。我在日志中最终得到的是大量相同的行,如下所示:

CACHE(0.0ms)SELECT * FROM external_categories WHERE(external_categoriesid = 216)

如果我避免给行提供所有唯一ID,它会完全打破页面(显然),但事情开始加载lickity split。

任何建议,备选观点或者你现在会非常感激的是什么。

提前致谢!

1 个答案:

答案 0 :(得分:0)

内置的acts_as_tree插件并不是很擅长,但有ancestry等替代方案支持root_id来解决此特定问题。

不需要更改任何内容的方法包括在下一步之后获取一个“级别”的深度,直到您的结果用完为止,大大缩短检索时间。

更好的方法是添加root_id列,以便非常快速地获取特定分支中的所有记录。但是,您必须在迁移中计算此值才能正确应用它。如果它只进行一次,那么这可能是一个缓慢的操作。

相关问题