1

好的,所以我有一个带有此架构的所有静态页面表

create_table "pages", :force => true do |t|
  t.string   "name"
  t.text     "html"
  t.string   "url"
  t.integer  "position"
  t.boolean  "is_home"
  t.integer  "parent_id",  :default => 0, :null => false
  t.string   "nav"
end

一个页面可以有另一个页面作为其父页面。这个想法是我希望用户完全控制导航和页面。所以我的问题是对这些页面进行分组的最佳方式是什么,以便在 html 中我可以遍历所有页面及其子页面

这是我到目前为止所拥有的

grouped_pages = Page.where(:is_home => 0).group_by(&:nav).each do |key, group|
 group.sort_by(&:parent_id)
end

我希望将它们分组到某个数组和/或哈希组合中,与另一个层一起使用,以获取具有另一个页面的 parent_id 的页面

页面结构看起来像这样

Page1
  Page3
    Page7
  Page4
  Page5
Page2
  Page5
  Page6

任何关于排序和循环以打印出 html 的 uls 的最佳方式的想法

4

2 回答 2

3

如果要允许任意嵌套树级别,最简单的解决方案是递归算法。例如(parent_id = NULL对于页面根,使用 ,而不是 0):

class Page < ActiveRecord::Base
  belongs_to :parent, :class_name => :Page
  has_many :children, :class_name => :Page, :foreign_key => :parent_id 

  def self.root
    where(:parent => nil).first
  end

  def tree
    [self, children.map(&:tree)]
  end
end

Page.root.tree 
#=> returns the structure in pairs [page, children]

从这里你可以做任何你需要的事情。例如,要设置排序标准,只需添加一个 options 参数tree并将其用于 scope children

请注意,要呈现树结构,您还需要一个递归助手来执行任务。实际上可能你不需要这个tree方法,只是一个调用的递归助手children,但想法是一样的。

正如 Mark 指出的那样,有一些 gem 可以实现 AR 树,例如acts_as_tree

于 2012-10-20T22:53:08.373 回答
1

使用像闭包树这样的宝石,您可以拥有相同的基本树行为,以及以下所有内容:

  • 具有所有层次结构的嵌套哈希
  • 一个节点的所有祖先的列表
  • 一个节点的所有后代
  • 一个节点的所有兄弟姐妹

和许多其他的,实现了只执行一个查询。

(See http://matthew.mceachen.us/blog/tags/closure-tree for reasons behind such a tree.)

于 2012-10-21T00:46:13.770 回答