sql – 如何将嵌套集中的所有记录呈现为真正的html树

我在我的Rails项目中使用了 awesome_nested_set插件.我有两个看起来像这样的模型(简化):
class Customer < ActiveRecord::Base
  has_many :categories
end

class Category < ActiveRecord::Base
  belongs_to :customer

  # Columns in the categories table: lft,rgt and parent_id
  acts_as_nested_set :scope => :customer_id

  validates_presence_of :name
  # Further validations...
end

数据库中的树按预期构造. parent_id,lft和rgt的所有值都是正确的.树有多个根节点(当然在awesome_nested_set中允许).

现在,我想在一个正确排序的树中呈现给定客户的所有类别,例如结构:例如嵌套< ul>标签.这不会太难,但我需要它才能有效(SQL查询越少越好).

更新:计算出可以在没有进一步SQL查询的情况下计算树中任何给定节点的子节点数:number_of_children =(node.rgt – node.lft – 1)/ 2.这并不能解决问题,但可能会有所帮助.

解决方法

如果嵌套集具有开箱即用的更好的功能将是不错的.

您发现的技巧是从平面集构建树:

>以一组按lft排序的所有节点开始
>第一个节点是根添加它,因为树的根移动到下一个节点
>如果它是前一个节点的子节点(prev.lft和prev.rht之间的lft)将一个子节点添加到树中并向前移动一个节点
>否则将树向上移动一级并重复测试

见下文:

def tree_from_set(set) #set must be in order
  buf = START_TAG(set[0])
  stack = []
  stack.push set[0]
  set[1..-1].each do |node|
    if stack.last.lft < node.lft < stack.last.rgt
      if node.leaf? #(node.rgt - node.lft == 1)
        buf << NODE_TAG(node)
      else
        buf << START_TAG(node)
        stack.push(node)
      end
    else#
      buf << END_TAG
      stack.pop
      retry
    end
  end
  buf <<END_TAG
end

def START_TAG(node) #for example
  "<li><p>#{node.name}</p><ul>"
end

def NODE_TAG(node)
  "<li><p>#{node.name}</p></li>"
end

def END_TAG
  "</li></ul>"
end

相关文章

SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_n...
if not exists(select name from syscolumns where name=&am...
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_n...
要在 SQL Server 2019 中设置定时自动重启,可以使用 Window...
您收到的错误消息表明数据库 &#39;EastRiver&#39; 的...
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标...