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のULを印刷するための最良の方法のアイデア

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 が指摘しているように、AR ツリーを実装するための gem があります ( acts_as_treeなど) 。

于 2012-10-20T22:53:08.373 に答える
1

gem のようなクロージャー ツリーを使用すると、同じ基本的なツリーの動作に加えて、次のすべてを行うことができます。

  • すべての階層を持つネストされたハッシュ
  • ノードのすべての祖先のリスト
  • ノードのすべての子孫
  • ノードのすべての兄弟

1 つのクエリのみを実行するように実装されています。

(このようなツリーの背後にある理由については、 http://matthew.mceachen.us/blog/tags/closure-treeを参照してください。)

于 2012-10-21T00:46:13.770 に答える