2016-01-13 17 views
10

私はモデルCourseModuleを持っていて、それぞれのモデルは同じモデルに関連しています。同じモデルの親子関係親密関係

データベース構造:モデルで

enter image description here

関係:

public function parent() 
    { 
     return $this->belongsTo('App\CourseModule','parent_id')->where('parent_id',0); 
    } 

    public function children() 
    { 
     return $this->hasMany('App\CourseModule','parent_id'); 
    } 

私は次のことを試してみましたが、それは関係の唯一のレベルを返します。

が試み:

CourseModule::with('children')->get(); 

私は次のようなJSON出力を作成しようとしている、

予想される出力:私はインナーを取得する方法を理解していない

[ 
    { 
    "id": "1", 
    "parent_id": "0", 
    "course_id": "2", 
    "name": "Parent", 
    "description": "first parent", 
    "order_id": "1", 
    "created_at": "-0001-11-30 00:00:00", 
    "updated_at": "-0001-11-30 00:00:00", 
    "children": [ 
     { 
     "id": "2", 
     "parent_id": "1", 
     "course_id": "2", 
     "name": "Child 1", 
     "description": "child of parent", 
     "order_id": "2", 
     "created_at": "-0001-11-30 00:00:00", 
     "updated_at": "-0001-11-30 00:00:00", 
     "children": [ 
      { 
      "id": "3", 
      "parent_id": "2", 
      "course_id": "2", 
      "name": "Child2", 
      "description": "child of child1", 
      "order_id": "2", 
      "created_at": "-0001-11-30 00:00:00", 
      "updated_at": "-0001-11-30 00:00:00", 
      "children": [ 
       { 
       "id": "4", 
       "parent_id": "3", 
       "course_id": "2", 
       "name": "Child 3", 
       "description": "child of child 2", 
       "order_id": "2", 
       "created_at": "-0001-11-30 00:00:00", 
       "updated_at": "-0001-11-30 00:00:00", 
       "children": [] 
       } 
      ] 
      } 
     ] 
     } 
    ] 
    } 
] 

子オブジェクト

答えて

3

このような深さがわからない場合は、子を再帰的に取得する必要があります。

別のオプションは、隣接リストモデルの代わりにネストされたセットモデルを使用することです。ネストされたセットの場合、Laravelにbaum/baumパッケージのようなものを使用できます。

"ネストされたセットは、高速で非再帰的なクエリを可能にする順序付けされたツリーを実装するスマートな方法です。" - あなたは完全なツリー階層を取得するために、すべての子どもたちと、ネストされた子どもたちとtoHierarchyを取得するgetDescendantsのようなメソッドを持って、このパッケージではhttps://github.com/etrepat/baum

Wikipedia - Nested Set Model

Baum - Nested Set pattern for Laravel's Eloquent ORM

Managing Hierarchical Data in MySQL

+0

こんにちは、 'CourseModule :: whereId($のID) - >最初の() - > getDescendantsAndSelf() - > toHierarchy()'を返すだけの単一ノード、私は、私は、モデルを変更する必要がありますトップに表示されているように1つのテーブルで作業しています –

+0

ありがとう@lagbox、それは働いた:) –

4

here私はあなたがツリー全体を検索するために再帰的にそれをしなければならないと思うあなた

を助けることができる答えである:

$data = CourseModule::with('child_rec'); 

再帰関数

これは、子どもたちの関係 にと親の関係にある(「親」)で、あなたの条件に応じて、あなたが(「子供」)を使用する必要があります

public function child() 
{ 
    return $this->hasMany('App\CourseModule', 'parent'); 
} 
public function children_rec() 
{ 
    return $this->child()->with('children_rec'); 
    // which is equivalent to: 
    // return $this->hasMany('App\CourseModule', 'parent')->with('children_rec); 
} 
// parent 
public function parent() 
{ 
    return $this->belongsTo('App\CourseModule','parent'); 
} 

// all ascendants 
public function parent_rec() 
{ 
    return $this->parent()->with('parent_rec'); 
} 
4

あなたを助けるかもしれ

あなたのコードの一部または他の出口の共同を持っていることを確認してください:あなたのコードの再帰

public function parent() 
    { 
     return $this->belongsTo('App\CourseModule','parent_id')->where('parent_id',0)->with('parent'); 
    } 

    public function children() 
    { 
     return $this->hasMany('App\CourseModule','parent_id')->with('children'); 
    } 

注意されるようにするには

それ以外の場合は、決して終わりのないループに終わるでしょう。

+0

それは動作します!最初のコレクションでは私は鎖の木を持っていますが、同じ子供たちは親コレクションとして繰り返されます。私はルートコレクションとして再び子供たちを望んでいない。解決策はありますか、間違っていますか? –

+0

解決策 '$ data = CourseModule :: with( 'children') - > where( 'parent_id'、0)'が見つかりました –

1

あなた自身の再帰関数を作成することはできますが、私の場合は以下のようにコードを実行します。

<?php 
declare(strict_types=1); 

namespace App\Models; 

use Illuminate\Database\Eloquent\Model; 
use Akmeh\Uuid; 

/** 
* Class Location 
* @package Domain\Models 
*/ 
class Location extends Model 
{ 
    use Uuid; 

    /** 
    * Indicates if the IDs are auto-incrementing. 
    * 
    * @var bool 
    */ 
    public $incrementing = false; 
    public $timestamps = false; 

    /** 
    * @param string $id 
    * @param array $tree 
    * @return array 
    */ 
    public static function getTree(string $id, array $tree = []): array 
    { 
     $lowestLevel = Location::where('id', $id)->first(); 

     if (!$lowestLevel) { 
      return $tree; 
     } 

     $tree[] = $lowestLevel->toArray(); 

     if ($lowestLevel->parent_id !== 0) { 
      $tree = Location::getTree($lowestLevel->parent_id, $tree); 
     } 

     return $tree; 

    } 

}