如何从awesome_nested_set呈现树并只访问数据库一次?

时间:2022-09-09 16:39:40

As the title states, I would like to render an ul-li-tree based on an awesome_nested_set model and hit the database only once. I'm using Ruby on Rails 4.1.

正如标题所述,我希望基于awesome_nested_set模型呈现一个ul-li树,并且只访问数据库一次。我使用的是Ruby on Rails 4.1。

My query looks like this:

我的查询是这样的:

Page.root.self_and_descendants.where('depth < ?', 2)

What would be an efficient way to do this?

有什么有效的方法可以做到这一点?

How can I iterate recursively through it, without loosing the where condition? For example, when I ask every Page instance, if it's a leaf (page_instance.leaf?), so it wouldn't stop at a depth of 2, but it wouldn't hit the database again until I digging deeper than 2. Can someone help me with the next foot step?

如何递归地遍历它,而不丢失where条件?例如,当我问每个页面实例时,如果它是一个leaf (page_instance.leaf?),那么它不会在深度为2时停止,但直到我深入到2时,它才会再次击中数据库。有人能帮我迈出下一步吗?

This question is related to a sitemap.

这个问题与站点地图有关。

1 个解决方案

#1


4  

If you really want to do it without any extra db queries, you may need to get them all and convert it into an array with .to_a and then re-create the tree structure in memory by iterating and constructing a hash.

如果您真的想不需要任何额外的db查询就完成它,那么您可能需要获取它们并将其转换为一个带有.to_a的数组,然后通过迭代和构造散列在内存中重新创建树结构。

However, there is something called a "closure tree" that is a really powerful way to do tree structures really fast in SQL, that some guys much smarter than me figured out. There is a ruby/rails gem that does it for you, and one of its features is to get an entire tree in a single SELECT statement, and puts it into a nested hash structure which would be perfect for your recursive iteration you're talking about. You may want to look into it: https://github.com/mceachen/closure_tree

但是,有一种叫做“闭包树”的东西在SQL中是一种非常强大的树结构快速处理方法,有些人比我聪明得多。有一个ruby/rails gem为您实现了这一点,它的特性之一是在一个SELECT语句中获取整个树,并将它放入一个嵌套散列结构中,这对于您正在谈论的递归迭代来说是完美的。您可能需要查看它:https://github.com/mceachen/closure_tree

But really, if your tree isn't that big, you may want to avoid the "premature optimization" and just do it the easy way, hit the database a few to a few dozen times (if you're always going to stop at level 2, the maximum number of queries is the number of children of the root).

但实际上,如果你的树不是那么大,你可能想要避免“过早优化”,只是简单的方法,达到数据库几个几十倍(如果你总是停留在2级,查询的最大数量是根的孩子的数量)。

#1


4  

If you really want to do it without any extra db queries, you may need to get them all and convert it into an array with .to_a and then re-create the tree structure in memory by iterating and constructing a hash.

如果您真的想不需要任何额外的db查询就完成它,那么您可能需要获取它们并将其转换为一个带有.to_a的数组,然后通过迭代和构造散列在内存中重新创建树结构。

However, there is something called a "closure tree" that is a really powerful way to do tree structures really fast in SQL, that some guys much smarter than me figured out. There is a ruby/rails gem that does it for you, and one of its features is to get an entire tree in a single SELECT statement, and puts it into a nested hash structure which would be perfect for your recursive iteration you're talking about. You may want to look into it: https://github.com/mceachen/closure_tree

但是,有一种叫做“闭包树”的东西在SQL中是一种非常强大的树结构快速处理方法,有些人比我聪明得多。有一个ruby/rails gem为您实现了这一点,它的特性之一是在一个SELECT语句中获取整个树,并将它放入一个嵌套散列结构中,这对于您正在谈论的递归迭代来说是完美的。您可能需要查看它:https://github.com/mceachen/closure_tree

But really, if your tree isn't that big, you may want to avoid the "premature optimization" and just do it the easy way, hit the database a few to a few dozen times (if you're always going to stop at level 2, the maximum number of queries is the number of children of the root).

但实际上,如果你的树不是那么大,你可能想要避免“过早优化”,只是简单的方法,达到数据库几个几十倍(如果你总是停留在2级,查询的最大数量是根的孩子的数量)。