2016-11-10 4 views
1

私は私のRailsアプリで以下のレコードいる:私はそうのようなリストでそれらをグループのレコードが

id: 1 
name: 'About' 
slug: 'about' 
permalink: '/about' 
parent_id: null 

id: 2 
name: 'Team' 
slug: 'team' 
permalink: '/about/team' 
parent_id: 1 

id: 3 
name: 'Cameron' 
slug: 'cameron' 
permalink: '/about/team/cameron' 
parent_id: 2 

を示しています。

:これはのようなリストを作成する

<ul> 
<% @pages.each do |page| %> 
    <li> 
    <%= page.parent.title rescue '' %><br> 
    <%= page.permalink %> 
    </li> 
<% end %> 
</ul> 

<ul> 
    <li>About<br>/about</li> 
    <li>Team<br>/about/team</li> 
    <li>Cameron<br>/about/team/cameron</li> 
</ul> 

ただし、parent_idを使用してグループ化する次のようなネストされたリストを作成します。

<ul> 
    <li>About<br>/about</li> 
    <li>-- Team<br>/about/team</li> 
    <li>---- Cameron<br>/about/team/cameron</li> 
</ul> 

コントローラーで簡単にグループ化する方法はありますか?


私が出ている最高のアイデアは、コントローラでこれを行うことです:ビュー内

@pages = Page.where(parent_id: nil)

そして、この:

部分的にを使用して
<% @pages.each do |page| %> 
    <%= render 'page_row', :page => page, :sub => 0 %> 
    <% page.pages.each do |page| %> 
     <%= render 'page_row', :page => page, :sub => 1 %> 
     <% page.pages.each do |page| %> 
      <%= render 'page_row', :page => page, :sub => 2 %> 
      <% page.pages.each do |page| %> 
       <%= render 'page_row', :page => page, :sub => 3 %> 
      <% end %> 
     <% end %> 
    <% end %> 
<% end %> 

巣を作りなさい:

<% 
    $i = 0 
    $num = sub 
    prefix = '' 
    while $i < $num do 
    prefix += '---' 
    $i +=1 
    end 
%> 
<li> 
<%= prefix %> <%= page.parent.title rescue '' %><br> 
     <%= page.permalink %> 
</li> 

しかし、私がやっていたように手作業でループすることで、ネストは4レベルまでしか制限されず、コードはあまり良くありません。

ページのネストされたビューを作成するために手動でループせずに同じ結果を得るにはどうすればよいですか?私はどうなるのか

+0

部分ページで@top_level_pages = Page.where(parent_id: nil)

ビューで

<%= render 'pages', pages: @top_level_pages, level: 0 %> 

あなたはレベルの一定の数を持っていますか、またはこれは理論的には無制限ですか? –

+0

無制限です。 – Cameron

+0

亀のように無制限に、無制限に3段階の柔軟性が必要です。前者は再帰を介して処理することができます。後者はSQL戻り値の順序句になり、ビューでgroup_byを使用します。 – engineerDave

答えて

2

私はあなたが正しい軌道に乗っていると思いますが、一定の回数だけループするのではなく、ビュー全体が再帰的でなければならないと思います。コントローラで

<% pages.each do |page| %> 
    <li> 
    <%= '-' * level %><%= page.name %><br> 
    <%= page.permalink %> 
    </li> 
    <%= render 'pages', pages: pages.pages, level: level + 1 %> 
<% end %> 
3

が同じモデルにモデル内の参照を作成している、つまり、の線に沿って何か:

@parents = Page.where(parent_id: nil) 

has_many :pages, foreign_key: 'parent_id' 

は次にトップレベルの親のすべてを取得します

は、それからちょうどビューで各親のためにすべての子をロードします。

@parents.each { |p| p.pages.each { |c| ... } } 

structuのこの種をまた、this SO threadで説明します。

+0

私はすでにモデルをうまくセットアップしました。 – Cameron

+0

これは2つのレベルしか処理しません。 – Cameron

+0

ツリーの下部に達するまで子を再帰的に探し続けることができます。 –

0

ビューレイヤーで必要なロジックを減らす方法でデータをカプセル化するツリー構造(JSONまたはハッシュ)を構築する新しいクラスを作成する必要があります。子供:あなたが再び部分を呼び出して渡す次の下位レベルを生成するために - 私はレベルごとにプレゼンテーションを定義するために、部分的に使用するビューで

{id: 1, 
name: 'About', 
slug: 'about', 
children: [ 
      { 
      id: 2, 
      name: 'Team', 
      slug: 'team', 
      children: [ 
         { 
         id: 3 
         name: 'Cameron' 
         slug: 'cameron' 
         ... 

。そのレベルの要素を反復する部分的な処理を行います。そして、どこに:子どもが存在し、それらを部分に再び渡します。

+0

しかし、どうしたらいいですか? – Cameron

+0

あなたはどの部分に苦労していますか? –

+0

最初の部分。 parent_idを使用してページをグループ化し、それらをループすることができます。例を見せてもらえますか?ありがとう。 – Cameron

関連する問題