好的,所以我有一个带有此架构的所有静态表
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
如果要允许任意嵌套的树级别,则最简单的解决方案是递归算法。例如(使用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]
由此您可以做任何您需要的事情。对于典范,要设置一个排序标准,只需将选项参数添加到 tree
并将其用于范围 children
。
请注意,要渲染树结构,您还需要一个递归助手来执行任务。实际上,您可能不需要此tree
方法,只是一个称为children
的递归辅助器,但这个想法是相同的。
正如马克指出的那样,有一些宝石可以实现AR树,例如ACTS_AS_TREE。
带有像闭合树一样的宝石,您可以具有相同的基本树行为,以及所有以下内容:
- 所有层次结构的嵌套哈希
- 节点的所有祖先列表
- 节点的所有后代
- 节点的所有兄弟姐妹
和许多其他人,仅执行一个查询。
(有关这棵树的原因