モデルCourseModule
があり、各アイテムは同じモデルに関連しています。
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": []
}
]
}
]
}
]
}
]
内側の子オブジェクトを取得する方法がわかりません。
そのような未知の深さがある場合、子供を再帰的に取得する必要があります。
別のオプションは、隣接リストモデルの代わりに入れ子集合モデルを使用することです)。 Laravel=ネストされたセットにはbaum/baum
パッケージのようなものを使用できます。
「ネストされたセットは、高速で非再帰的なクエリを可能にする順序ツリーを実装するスマートな方法です。」 - https://github.com/etrepat/baum
このパッケージには、すべての子とネストされた子を取得するgetDescendants
や、完全なツリー階層を取得するtoHierarchy
などのメソッドがあります。
子関係ではwith('children')
を使用し、親関係ではwith('parent')
を使用する必要があります。
コードを再帰的にするには:
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');
}
注:コードに何らかの終了条件があることを確認してください。そうでない場合、終了しないループになります。
ここ はあなたを助ける答えです
ツリー全体を取得するには、再帰的に実行する必要があると思います。
$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');
}
いつでも独自の再帰関数を作成できます。私の場合は、次のようにコードを作成します。
<?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;
}
}
モデル機能:
public function Children()
{
return $this->hasMany(self::class, 'Parent', 'Id')->with('Children');
}
コントローラー機能:
Menu::with("Children")->where(["Parent" => 0])->get();
モデルの関係はこのようにする必要があります
// parent relation
public function parent(){
return $this->belongsTo(self::class , 'parent_id');
}
//child relation
public function children()
{
return $this->hasMany(self::class ,'parent_id');
}
public function ascendings()
{
$ascendings = collect();
$user = $this;
while($user->parent) {
$ascendings->Push($user->parent);
if ($user->parent) {
$user = $user->parent;
}
}
return $ascendings;
}
public function descendings()
{
$descendings = collect();
$children = $this->children;
while ($children->count()) {
$child = $children->shift();
$descendings->Push($child);
$children = $children->merge($child->children);
}
return $descendings;
}